14

Our web mapping requirements are fairly standard - some basic querying and the ability to print out the resulting map (or save the image). Typically we've used ESRI products in the past (right now we're using GeoCortex) but we still haven't been able to solve the problem of how to parse the legend information to match what is actually being shown on the map. For example, if there are four polygons showing up on the map, there should only be four legend items for the polygons. Is there an open source solution for this problem?

EDIT: Let's see if I can clarify this more. Currently, we have a geology layer with 33,000+ polygons. The legend for this layer is a single image and contains several hundred legend items (ie. it's the legend for the entire geology layer, stored in a JPEG/PNG).

Typically, a user will zoom in on an area (such as a single NTS map sheet, or even smaller) and so a subset of geology polygons will be shown on screen. They will then save the map as a print document (PDF or image), which is generated by GeoCortex/ArcGIS Server. The print document will contain a header, an image of the map and a legend. However, the legend for the geology layer will be the legend for the entire geology layer, not what is actually shown on the map (ie. a much smaller subset).

So, I'm looking to see if there is a FOSS solution to enable me to clip out or generate on the fly an subset of the geology legend which reflects the actual items on-screen/on the map, to go with the print document. I hope that clarifies things; I apologize if it doesn't!

6
  • 1
    Hi ollyoop- I'm having a hard time envisioning your desired result. Can you include an example of the bad legend, and an example of a good legend? I think that might help me or others give an answer. Thanks--
    – andytilia
    Commented Nov 9, 2012 at 22:46
  • this feature has been included in Arcgis server 10.1, i have seen it during a presentation of ESRI.
    – geogeek
    Commented Nov 14, 2012 at 10:12
  • Hmmm, well, we'll see how that actually works out. In the meantime, are there any FOSS solutions?
    – ollyoop
    Commented Nov 14, 2012 at 14:40
  • 1
    FOSS or ESRI-based, it sounds like you will need custom code. Commented Nov 14, 2012 at 22:39
  • Surely Latitude Geographics can do this. Have you spoken with them about it (whether or not it's already in Geocortex Essentials or if they plan on implementing it)? Commented Nov 16, 2012 at 17:11

4 Answers 4

5
+150

AFAIK, in FOSS4G or ESRI, you will need to write custom code to generate this layer.

It is not that difficult, but it will take you more than a few lines of code.

For ArcMap, this is accomplished using a Custom Element. The ESRI help site is filled with old examples and new examples.

In the past, I have accomplished something similar to what you described using Pagelayout Frame Elements.

If you have never done ArcObjects (but have programmed), the drawing code can get a bit tricky, but it usually takes making one to reach that "aha!" moment.

The algorithm is simple:

  • (1) Get the Map object of the PageLayout that you want to use as reference for generating the legend...You may have to deal with multiple frames to reach the map that you want, because a Pagelayout can contain several Map objects with different extents which is a bit unusual if you have not done any custom ArcMap Pagelayout programming (think about the little inset maps that you can have).

  • (2) Grab the Visible Extent of the ActiveView of the map you want.

  • (3) Use that as your query filter geometry to loop and search through all layers in the map.

  • (4) If the layer returns any records, you have to draw it as shown in the examples I gave you before.

Sorry I cannot offer you an easier solution, but at least this way you will be able to make it look however you want it to look - just coding required.

Update:

Since you wanted to do this in the context of a Web application, I checked the documentation and there are several ways of doing it using a similar algorithm.

One of these is through an ArcGIS Server Object Extension. You would do all the steps except (1) (no need to worry about Pagelayout in this context). Expose the result using REST.

From here, you have several options (based on if you want to use Flex or Javascript), but the idea is the same - on page refresh call the REST webservice you created and draw the legend.

The advantage to this approach as opposed to others that have been suggested is that you can use any symbology with your features (and are not limited to distinct colors for the symbology of the feature). You can use your favorite web language for the client side code. The symbols that you generate for the legend can be automatically generated from the map.

The disadvantage, is that you will need to write a Server Object Extension! Luckily, there is an ESRI sample that does 75% of what you need already and should give you a clear idea of how to continue with the comments I made above.

Update 2: As far as a FOSS4G solution to this, the same approach would also work with any of the FOSS servers, albeit the API is slightly different for each.

3
  • 1
    Thank you very much for the answer! There's a tool called Legend Limiter that already does this for the ArcGIS environment. What I'm looking to do is port that ability to the web mapping world.
    – ollyoop
    Commented Nov 16, 2012 at 21:53
  • @ollyoop At least until 9.3, I know this same approach would have worked completely fine for ArcGIS Server. I know there has been significant changes in the server rendering architecture since 9.3, and I admittedly have not kept up with that. I would be surprised if custom elements were yanked out of 10.1 though. Commented Nov 17, 2012 at 2:47
  • @ollyoop added an approach that would work with ArcGIS Server Commented Nov 19, 2012 at 17:34
3

It is definitely possible to do what you want, depending on certain conditions. Take a look at this Flex App I had developed a couple of years back: http://india-wris.nrsc.gov.in/LULCApp.html.

The Legend and the Stats, change depending on the data visible in the current extent. The Algorithm requires that each of the class have a distinct color. The Flex Application knows the class, and its colour. At every extent change, it converts the current map extent to a bitmap, and then finds out the colours in it. Using this, you can find out which colours or classes are currently visible. Based on this information, the legend is dynamically created.

I had used Flex at that time, but this is also possible using the Canvas in HTML5. Or you can use any Server side code to do the same thing to your map image to get your dynamically created legend.

1
  • That's exactly it! Great to see an example in practice. Much appreciated!!!
    – ollyoop
    Commented Nov 16, 2012 at 21:55
3

When you export to a PDF with Geocortex Essentials, the legend is generated by a subreport in the print template. This subreport receives all of the visible layers that were used to create the map image, and all of the legend swatches as produced by ArcGIS Server. It does not issue any spatial queries to determine if any layers in the legend are actually drawn at the extent of the printed area.

So, if you wish to change the behaviour of the legend, you can customize the legend subreport, or you can use an image instead of a subreport to put a legend into the print template. If you're already generating a legend image somehow for use in your viewer, you should be able to re-use that service from the print engine.

The legend already contains some embedded inline code that toggles the formatting for the legend text based on if the swatch is for a layer or for a class in the layer. You can see the inline code when switching to the "Scripting" tab in the report designer.

(I work at Latitude Geographics)

1

About "web mapping" with full "FOSS solution"... Considerations:

  • The "FOSS solution" must be "popular" (have a big and organized community) to be safe, stable, etc.
  • A key concept in FOSS and GIS is standardization: the best solutions adopt standards, like OGC ones.
  • Today the popular "web solutions" are OpenLayers, Mapserver, GeoServer, PostGIS, etc. All they have some OGC-compliant core. The "GeoCortex/ArcGIS Server" solution is not FOSS, but, perhaps, OGC-compliant.

And technical consideration: you are using "coverages" (?), so a good OGC-standard for retrieving your spatial information is the WMS.


An OGC-compliant simple solution to your problem, is to use the WMS GetCapabilities and GetLegendGraphic services, that returns a standard legend description into an XML file, and the image with legends.

NOTE: when you think about some GIS/FOSS solution, you can think first with standards, then the problem is reduced to a "well-known LEGO pieces problem", and the pieces came from any vendor.

ArcGIS 10+ have GetLegendGraphic, but check if you can specify BBOX for show only a legend-subset.


If you want to build a layout of map with legend, there are another pieces of this "FOSS LEGO solution":

Any FOSS map server, like MapServer (and I think that ESRI solutions too), can offer a JPEG image as a WMS (not-tiled) map request -- see WMS's GetMap service.

PS: it is not a standard, but perhaps your server can by configured to offer map with legend, by template tools, like MapServer.

To build a layout of "map with legend" you can can generate a HTML (or "PDF file on fly") with Javascript, PHP or another language that do the (REST) web service requests for map and legend.

I prefer to generate PDF from HTML: you can use wkHtmlToPdf, a FOSS solution for HTML-to-PDF convertions. To produce poorer layouts, with "on fly JPEG layout", you can use a standard FOSS toolkit, like imagemagick, at server.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.