Using Python, I have an api with security incidents that I want to populate into a feature service layer. I've achieved this successfully using Add Features via the ArcGIS REST API endpoint (described here). However the original point feature class is stored in SDE, which has a defined coordinate system - WGS 1984 Web Mercator (Auxiliary Sphere)
Therefore my points are being added with the wrong projection (because I'm adding using the just geographic coordinates).
Are there any programmatic solutions to change the geometry to a matching projection before adding the features? Or some other work around to match the projection?
My (slightly modified) working code is included. Basically I have two functions - the first one grabs the API data and then returns a list of reformatted features. Then, the next function takes that list as input and adds each feature to the feature service layer.
import urllib
import requests
import json, time
from datetime import datetime
import unicodedata
def getFeaturesReformatPayload(api_url):
''' Requests API, returns list with reformatted payload for adding features.
'''
# get planet risk data
print('Getting Planet Risk data...')
response = requests.get(api_url)
if response.status_code == 200:
print("Success")
else:
print("There was an error")
payload = response.json()
# reformat the payload to be added to feature layer
payload_reformatted = []
for i, x in enumerate(payload['result']['resourceList'][0]['resource']):
# convert datetime in time cols - 'updated', 'created'
created_time = x['created'][:-3] # shortened epoch to seconds
# print('Length of created timestamp: {}'.format(len(str(created_time))))
updated_time = x['updated'][:-3]
# print('Length of updated timestamp: {}'.format(len(str(updated_time))))
# convert unicode to string
created_time_str = unicodedata.normalize('NFKD', created_time).encode('ascii', 'ignore')
updated_time_str = unicodedata.normalize('NFKD', updated_time).encode('ascii', 'ignore')
created_formatted = datetime.fromtimestamp(float(created_time_str))
updated_formatted = datetime.fromtimestamp(float(updated_time_str))
# copy dict then update formatted time in the dict
copy_dict = x.copy()
copy_dict.update({'created': str(created_formatted)[:10]}) # removing timestamp - just date
copy_dict.update({'updated': str(updated_formatted)[:10]})
# print('Feature #: {} , was created on {}, and was last updated on {}'.format(i, created_formatted, updated_formatted))
# create geometry - delete unwanted fields - append to reformatted
geometry_dict = dict(y = x['lat'], x = x['lng'])
deleteFields = ['lat', 'lng', 'resourcetype', 'id']
for x in deleteFields:
copy_dict.pop(x)
payload_out = dict(attributes = copy_dict, geometry = geometry_dict)
payload_reformatted.append(payload_out)
print('Total Number of Incidents: {}'.format(len(payload_reformatted)))
return payload_reformatted
def addIncidentsToFSL(input_payload):
''' Adds input payload to the feature service layer via proxy.
'''
# proxy bypasses authentication
proxy_path = "https://servername.example.net/DotNet/proxy.ashx?"
feature_layer_endpoint = "https://servername.example.com/arcgis/rest/services/National/examplePublishedMXD/FeatureServer/3/addFeatures"
url = "".join([proxy_path,feature_layer_endpoint ])
# print(url)
for i, k in enumerate(input_payload):
print('\nAdding Incident to Feature Service Layer: {}'.format(i))
payload_body = {'f': 'json', 'features': json.dumps([input_payload[i]])}
# print(payload_body)
print('...')
r = requests.post(url, data = payload_body, verify = False)
# print response
if r.status_code == 200:
print('Success')
else:
print('Failed')
# wait 3 seconds
time.sleep(3)
if __name__ == "__main__":
# define api, get features, reformat, add to feature service layer
example_api = 'string_with_apiURL'
reformatted_payload = getFeaturesReformatPayload(example_api)
addIncidentsToFSL(reformatted_payload)
print('All Features Added from API to Feature Service Layer')