POST random points as ESRI JSON to a REST endpoint

During one of my experiments with GeoEvent Server GeoEvent Extension for Server, I needed to test out real-time streaming. Having only dabbled with JSON before, it was time for me to get real. To Python!


#
# @date 13/05/2015
# @author Cindy Williams
#
# Creates a point feature class in memory containing
# random points within a predefined extent, and posts
# the points as ESRI JSON to a REST endpoint.
#
# For use as a standalone script
#
import json
import requests
import random
import os
import arcpy
from string import ascii_uppercase
arcpy.env.outputCoordinateSystem = arcpy.SpatialReference(4326)
headers = {'Content-Type': 'application/json'}
url ="" # Insert REST endpoint here for POST
ext = "17.7556923735604 -34.8330442856367 24.2223940143152 -30.4302569614079" # Predefined extent
gdb = r"in_memory"
ftr = "randompts"
points = os.path.join(gdb, ftr)
def attrToesriJSON(x, y, name):
# Format for ESRI JSON
return {"attributes":{"Name":name}, "geometry":{"x":x,"y":y}}
arcpy.management.CreateRandomPoints(gdb, ftr, "", ext)
arcpy.management.AddField(points, "Name", "TEXT", "#", "#", 10)
with arcpy.da.UpdateCursor(points, ("SHAPE@XY", "Name")) as cursor:
for row in cursor:
# Assign a random label to each point. Not worried about repeating IDs here
row[1] = random.choice(ascii_uppercase) + str(random.randrange(1000, 10000))
cursor.updateRow(row)
# Generate the JSON
data_json = json.dumps(attrToesriJSON(row[0][0], row[0][1], row[1]))
# Post the JSON
response = requests.post(url, data=data_json, headers=headers)
# Optional: persist to disk
arcpy.conversion.FeaturesToJSON(points, r"C:\Some\Arb\Folder\randompts.json")

I’d like to point out that even though I only wrote this script 4 months ago, I’ve learned enough in the meantime to want to rewrite this script. I’d still like to walk it through it though, because the tweaks I would like to make to it are more optimisations/best practice than fixing any bugs.

IIRC, this was my first dalliance with the delightful requests module. In Line 22, I used the url provided by GeoEvent after setting up a “Receive Features on a REST Endpoint” input connector. In Line 23, I manually entered an extent I had determined using a technique I like to call “looking at it in ArcMap”. This extent is used in the Create Random Points geoprocessing tool to constrain the area in which random points would be created.

(I’ve been moving away from using geoprocessing tools available in arcpy, in favour of pure Python. Instead of calling the Create Random Points tool, I would rather use the random tool to generate the coordinates and then physically build the point geometries.)

In the search cursor, after processing every row as JSON and assigning a random label, the JSON is POSTed. What this does mean is that the REST service is going to get hammered with those points one after the other. For testing purposes, only a small set of points were generated, and the server can easily handle the load.

What if, in some future scenario, I have (hundreds of) thousands of points trying to get through at the same time? I can’t easily think of such a scenario, but since I’ve been moving more and more into development, I’d like to keep these things in mind.

Display line geometry in a SharePoint List using ESRI Maps for SharePoint

A while ago I was asked to find out how to display line geometry on a map using SharePoint lists. After some creative googling, I came across an ESRI thread, and another one, which pointed me in the right direction. This example uses a single line feature to demonstrate the methodology I developed.

In ArcGIS:

  1. Convert the line feature to JSON using the tool or using Python (my preferred method):


    #
    # @date 29/04/2015
    # @author Cindy Williams
    #
    # Converts geometry in a feature class to JSON,
    # and writes it to a CSV file.
    #
    # For use in the Python window in ArcCatalog.
    #
    import arcpy
    arcpy.env.workspace = r"C:\Some\Arb\Folder"
    lyr = arcpy.management.MakeFeatureLayer("work.gdb\ftr_line")
    outcsv = r"line_json.csv"
    # Get geometry of first feature as JSON
    lyr_json = arcpy.da.SearchCursor(lyr, "SHAPE@JSON").next()[0]
    # Write JSON to CSV
    with open(outcsv, 'wb') as csvw:
    csvw.write(lyr_json)

    Of course you can save the file immediately as a JSON file, but I am so used to writing it out to CSV that I automatically put that there.

In your SharePoint site:

  1. Create a custom list (or open your existing one).
  2. Add a plain text column called Shape of type Multiple Lines (not sure if this is a requirement, but I figured it couldn’t hurt). As mentioned in the thread, the column must be created with the correct title – renaming an existing column will not work.
  3. Add a ESRI Maps Location column to the list. Under Location Settings > Coordinate Fields, select Shape. The field dropdown should automatically populate the Shapecolumn we added earlier.
  4. Start editing your list.
  5. Create a new record in your list, and populate your attributes. Copy the JSON string from the file created earlier and paste it into the Shape column.

Here is the result (click to enlarge):

SharePoint_JSON

JSON representation of a line in a SharePoint list using ESRI Maps for SharePoint

This is a nice way of storing commonly accessed features such as study area boundaries, in a central list without a dependency on map services hosted on ArcGIS Server or ArcGIS Online.