Skip to content

Instantly share code, notes, and snippets.

@JeffJacobson
Created January 3, 2012 19:07
Show Gist options
  • Save JeffJacobson/1556375 to your computer and use it in GitHub Desktop.
Save JeffJacobson/1556375 to your computer and use it in GitHub Desktop.
Exports the legend from an ArcGIS Server map service as an HTML document.
"""Exports the legend from an ArcGIS Server map service as an HTML document.
Parameters:
0 ArcGIS Server map service legend URL
1 Inline Images (optional)
If this parameter is set to any value, the images will be included inline
in the CSS instead of being saved to separate image files. (Note that this
method is not supported by Internet Explorer 7.)
"""
import sys, re, base64, httplib, json
# Load the legend into a dictionary.
connection = None
legend = None
legendUrlRe = re.compile(r"http://(?P<host>[^/]+)(?P<url>[^\?]+)")
# Set a default URL in case none was provided at the command line.
url = r"http://example.com/ArcGIS/rest/services/MyMapService/MapServer/legend?f=pjson"
# Read the URL provided at the command line.
if len(sys.argv) > 1:
url = sys.argv[1]
# See if it is a valid URL. Split into host and url components.
urlMatch = legendUrlRe.match(url)
if urlMatch:
host, url = urlMatch.group("host"), urlMatch.group("url")
print host, url
else:
raise "Invalid URL"
try:
connection = httplib.HTTPConnection(host)
connection.connect()
connection.request("GET", url + "?f=json")
response = connection.getresponse()
legend = json.load(response)
finally:
if connection is not None:
connection.close()
del connection, response
# Set a switch to indicate if inline images will be used in the CSS.
useInlineImages = len(sys.argv) > 2
# Initialize the strings for html and css content.
html = "<!DOCTYPE html><html><head><meta http-equiv='Content-Type' content='text/html;charset=utf-8' /><title>Legend</title><link rel='stylesheet' href='legend.css'></head><body>"
css = ""
imgMimeRe = re.compile(r"(?<=image/)\w+", re.IGNORECASE)
# loop through all of the layers
for layer in legend["layers"]:
# add a heading for the layer name
html += "<h2>%s</h2>" % layer["layerName"]
# add a <ul> for each layer.
html += "<ul>"
# initialize the legend ID number.
legendId = 0
for legend in layer["legend"]:
legendName = "layer%slegend%s" % (layer["layerId"], legendId)
if useInlineImages:
# Write inline image styles into CSS file content string.
dataUrl = "data:%(contentType)s;base64,%(imageData)s" % legend
css += "#%s {list-style-image: url(%s)}\n" % (legendName, dataUrl)
else:
# =Create image file...=
# Generate a filename based on the legend name and content type.
legendImageFileName = "%s.%s" % (legendName, imgMimeRe.search(legend["contentType"]).group(0))
# Write the image data to the binary file, overwriting any existing data.
with open(legendImageFileName, "wb") as pngFile:
pngFile.write(base64.decodestring(legend["imageData"]))
# Add CSS definition to CSS content.
css += "#%s {list-style-image: url('%s')}\n" % (legendName, legendImageFileName)
# Add the list item to the HTML content string.
html += "<li id='%s'>%s</li>" % (legendName, legend["label"])
legendId += 1
# Close the ul element.
html += "</ul>"
# Close the body element.
html += "</body>"
with open("legend.html", "w") as htmlFile:
htmlFile.write(html)
with open("legend.css", "w") as cssFile:
cssFile.write(css)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment