Archive

Posts Tagged ‘WMS’

Choosing the optimal configurations for GeoServer

December 29, 2011 1 comment

What I wanted to do

Setup GeoServer with optimal performance. I define optimal performance as fast response with large number of concurrent users (HTTP request of WMS). The GeoServer will be serving vector line data with 80K features. The vector lines are currently stored as a feature class in ArcSDE with Oracle.

Problems

I have identified several parameters/configurations could improve the performance of GeoServer at OpenGeo and GeoServer’s documentation. In particular, here are a list of big questions that I need to answer:

1. What are the optimal JVM options

2. Which application server shall I use to serve GeoServer, Tomcat or Glassfish?

3. Which source data format shall I use to feed GeoServer? Shall I stay with ArcSDE or shall I export the feature class to a shapefile?

Here is the verision of some applications that I used:

  • Tomcat 6.0.33
  • Glassfish 3.1
  • GeoServer 2.1.1
  • JRE 1.6
  • ArcSDE 9.3.1
  • Oracle 11g

Solution

To find answers, I need to do some testing and find out what set of configurations give me the fastest HTTP response when GeoServer handles WMS request. To measure the testing result, I found an excellent tool called JMeter. It basically issues customized HTTP request to specified web service and measures the response time. It can also do the testing for multiple-user scenario.

I started with JVM options. A benchmark was established with default JVM settings, Tomcat, ArcSDE as source data format, and single user scenario. Then I changed one parameter for JVM option at a time, measured the response time and compared the result against the benchmark.

After finding the optimal JVM options, I switch the source data format from ArcSDE to shapefile and continue to run the testing on single user scenario.

Then I switched to multiple-user scenario with 10 users sending requests at 1 second interval. In this case, GeoServer’s performance decreases dramatically for either shapefile or ArcSDE as source data format.

I also did similar test with Glassfish.

Here is my findings:

Optimal JVM options: -server -Xms1024m -Xmx1024m -XX:MaxPermSize=512m -XX:+UseParNewGC. Of course, these options depend on the hardware configuration of my machine

Tomcat vs. Glassfish

  • In single user case: Glassfish is faster than Tomcat
  • In multiple user case: Tomcat is faster than Glassfish but more volatile. On average, Tomcat responses faster. But comparing with Glassfish, a lot more of Tomcat’s responses are either faster or slower, making the response time less predictable in Tomcat.
  • With user number increases, response time increases too. But Glassfish’s response time increases more than Tomcat for the same number of user increase

ArcSDE/RDBMS vs. Shapefile

  • In general, shapefile is faster than ArcSDE/RDBMS. In single user scenario, shapefile is more than 10 times faster than ArcSDE. This is reasonable because when ArcSDE is involved there is overhead of connecting to database. Even if there is database connection pooling in Tomcat, the overhead is still very costly
  • In multiple user case: response time increase for ArcSDE is less than shapefile. This is reasonable as RDBMS is designed to handle concurrent users scenario
  • In my 10-concurrent user scenario, even shapefile’s performance decreased more dramatically than ArcSDE with user increase, it still perform about 10 times better than ArcSDE. But I think with more and more concurrent users (100, 1K even 10K), ArcSDE/RDBMS’s performance should eventually out beat shapefile

So, if I want stability in performance, fast response time, AND if I predict only very small number of concurrent users, I should go with Glassfish and shapefile. In the case of large number of concurrent users, it seems that the combination of Tomcat and ArcSDE/RDBMS  should lead to better performance.

Advertisements

Wrap data around 180 longitude with ArcGIS Server and JavaScript API

What I wanted to do

I have data extends across 180 longitude. When I build a web map out of the data, I want it to be wrapped around 180 so that I can pan the map across 180. To achieve that, according to samples in ArcGIS JavaScript API 2.3, I need dynamic map service published by ArcGIS Server 10 and add “wrapAround180:true” to the options of esri.Map.

What I have

  • Shapefile
  • ArcGIS 10
  • ArcGIS Server 10

Solution

First of all, what is dynamic map service? My understanding of dynamic map service after reading Publish Map Service in ArcGIS 10 Desktop Help is that as long as the map service is not cached, it is dynamic map service. So I followed the steps listed in the help to publish my data as a map service with WMS, with caching set to “Draw this map service dynamically” in the service setting in ArcGIS Server. Then in the web map that I built with ArcGIS JavaScript API, I set the map to wrap around 180 (var map = new esri.Map(“MyMapID”, {wrapAround180:true})) and created a layer consuming the WMS (var wmsLayer = new esri.layers.WMSLayer(“the WMS layer”)).

It didn’t work. The map was still cut off at 180.

After some internet research, I found out that to make the wrap around 180 work, I need to create a ArcGISDynamicMapServiceLayer and the layer has to consume a REST service. So now the question became how to create a REST service.  According to ArcGIS Server REST API, to find out the REST services on my ArcGIS Server, I used http://<host&gt;:8399/arcgis/rest. My data was not there, even through I have published my data as map service. After talking to someone who have experience with REST service, I found out that the problem is related to REST service caching. On my ArcGIS Server, the caching has to be cleared manually, which is why my data didn’t show up in the REST service directory. To manage the REST service, I used http://<host>:8399/arcgis/rest/admin. Once the cache is cleared manually, my data showed up.

Now, instead of a WMS layer, I create a dynamic map service layer in my web map (var restLayer = new esri.layers.ArcGISDynamicMapServiceLayer(“http://<host&gt;:8399/arcgis/rest/services/MyData”)) and guess what, my data goes across 180 now!

How Google Fusion Table made my life MUCH easier


Google Fusion Table is still in Beta. But it’s powerful! There are so many things you can do with Google Fusion Table and as far as I am concerned it has THE potential in many ways to redefine how GIS professionals mange and publish GIS data.  I am going to give you one little example to demonstrate that and show you how it made my life much easier.

What I wanted to do

Build a web map that consumes my GIS data. I wanted user be able to click on the feature on web map to get attributes of the selected feature

What I have

  • My GIS data in ESRI Shapefile
  • WMS of my data served out by GeoServer
  • Email from my department telling me that ArcGIS Server is too expensive to purchase

Issue

I built a web map with OpenLayers, and Google Map as background. It consumes WMS served out by GeoServer. When user clicks on the feature on web map, the attributes of clicked feature are displayed on the webpage below the map. This seems to be fine. But:

  1. A proxy to handle cross-site scripting problem was introduced into this web map so that when user clicks on the feature, the attributes actually show up. This is a known security risk and even though the proxy mechanism works in a test environment, my organization won’t allow this proxy thing to happen when the web page goes public
  2. I spent lots of effort to program OpenLayers, Google map, WMS and the CGI for proxy on my web page so that they work well together but in the end all these efforts are wasted because of the security risk

Solution

I tried Google Fusion Table and its a perfect way to work with in my situation.  Google Fusion Table allows you to do the following cool things:

  1. Upload spatial data in KML format
  2. Plot uploaded spatial data on Google Map
  3. When clicking on the spatial data on Google Map, you get popup of the attributes

So I use ArcGIS to convert my shapefile into KML and upload the KML into a fusion table. Once my data is in a fusion table, I clicked on Visualize -> Map to get a Google Map view.  On top of the Google Map, I can “Get embeddable link” of my data in a Google Map view. Then I use this link on my web page for the web map. See the bottom of this post for how my data looks like. Just in case you haven’t realize the huge benefit of using Google Fusion Table in my situation:

  • I don’t need a sever
  • I don’t need to program OpenLayers and WMS etc.
  • I don’t need to worry about cross site scripting security risk. Speaking of security risk, my data is not sensitive so I have no concern of data security

I highly recommend anyone who works in professional GIS arena try Google Fusion Table. It is definitely redefining how we publishing and sharing GIS data.

Create Complex Line Style with GeoServer 2.x

GeoServer recently released 2.1.0. Among all the impressive improvements, I found line styling improvements most helpful for me. Prior to 2.x, there is nothing you can do but scratching your head when it comes to creating line style of alternating symbols, not to mention using custom smybol in the alternating symbols line style. 2.x is a dream comes true for me.

What I wanted to do:

Create a line style with alternating plus and minus sign and a fish symbol. Like this:

What I have:

Solution:

To create a line style like that, I need a “+” symbol, a “-” symbol, and a fish symbol. For “+” symbol, I use well known name “Cross”. For “-” symbol, there is no well know name symbol so I use dash line instead to create the effect of “- – – “. and “-” symbol. For fish symbol, I have two source options: create my own or snapshot one from an existing image using any software that can clip an image. I also need to choose a graphic format to store the fish symbol. I decided to go with SVG instead of raster-based format such as JPEG and PNG because JPEG or PNG image might be resampled when you specify a pixel size of the image in the SLD that is different from the image’s original size. The resampling made the image look really ugly on map. Here is what I did to create the sytle:

  1. Create a fish symbol using Online Paint
  2. In SLD, set a FeatureTypeStyle with two LineSymbolizer. One line symbolizer with “+” and make it dashed graphic stroke. Set another line symbolizer with just stroke and make it dashed, which create a style of “- – – -“.  Combining this two symbolizers together gives me something look like “+-+-+-+-“
  3. Set another FeatureTypeStyle with  line symbolizer of external graphic. The external graphic is the fish symbol created in step 1. Make the line dashed so that the fish appears on the line every few pixels
  4. Apply the SLD to the line layer in GeoServer
  5. Played with the numbers in SLD (width, dasharray and dashoffset) for a while to get the best symbol size, line weight and interval between symbols

Here is the SLD code example: LineStyleSLD

Note: GeoServer 2.x allows user to create marks with True Type Font (TTF). But watch out if your testing operating system is different from your operational operating system. When you test in Windows environment, TTF is accessible. But then when you move the tested SLD to GeoServer running on Linux, the marks defined in TTF probably won’t show up because the TTF is not installed on Linux.

Make GetFeatureInfo work for WMS map

What I wanted to do:

  • Create a webpage with map using OpenLayers. The map consumes a WMS from my GeoServer
  • Get attributes of the data when I click on a feature on the map. The attributes will be displayed under the map in a table

What I have:

Issue:

  • I followed examples of GetFeatureInfo to create WMS overlay on Google map using OpenLayers. It worked well. But nothing showed up when I click feature on the map: GetFeatureInfo didn’t work

Solution:

The problem is due to JavaScript’s security restriction on cross site XMLHttpRequest (See ProxyHost section in http://trac.osgeo.org/openlayers/wiki/FrequentlyAskedQuestions). To solve this problem, I need a proxy to bypass this restriction. To follow “How do I setup ProxyHost?” in the FAQ and some other Q&As on the internet, I did the following:

  • Install Apache HTTP server on my PC
  • Get proxy.cgi from http://trac.osgeo.org/openlayers/browser/trunk/openlayers/examples/proxy.cgi
  • Change python path on the top line of proxy.cgi to my python executable (#!C:/Python26/ArcGIS10.0/python.exe -u;)
  • Add ‘localhost:8080’ in allowedHosts in proxy.cgi. This allows the proxy to work for GeoServer
  • Copy proxy.cgi to /cgi-bin under Apache folder on my PC
  • Start up Apache
  • To test the proxy.cgi, I ran http://localhost/cgi-bin/proxy.cgi, which redirected me to the homepage of OpenLayers.org
  • Copy my webpage Test.html to /htdocs under Apache folder (where I pretend I am going to serve out my webpage)
  • Add OpenLayers.ProxyHost = “/cgi-bin/proxy.cgi?url=”; on the webpage
  • Start up GeoServer
  • run the webpage from localhost/Test.html
It worked!
Categories: Web GIS Tags: , ,