Arcpy way to access underlying feature classes contained in a web mapDelete SDE feature class features with...
Count repetitions of an array
Renting a 2CV in France
Does it take energy to move something in a circle?
Taking an academic pseudonym?
Why does this relation fail symmetry and transitivity properties?
Solving the linear first order differential equation?
Sensor logger for Raspberry Pi in a stratospheric probe
Why do neural networks need so many examples to perform?
Why are mages sometimes played bot instead of traditional ADCs?
Coworker asking me to not bring cakes due to self control issue. What should I do?
How to align the top of the text with the top of a figure produced by tikz in minipage
Does the US government have any planning in place to ensure there's no shortages of food, fuel, steel and other commodities?
Equivalent of "illegal" for violating civil law
Is Screenshot Time-tracking Common?
How to check if remote-signer is working as expected?
Why is "rm -r" unable to delete this folder?
Critique vs nitpicking
How do I narratively explain how in-game circumstances do not mechanically allow a PC to instantly kill an NPC?
Buying a "Used" Router
What species should be used for storage of human minds?
Possible issue with my W4 and tax return
How can I take a waterfall's effect on a jump into consideration mechanically?
What are some ways of extending a description of a scenery?
How to put text above column in minipage?
Arcpy way to access underlying feature classes contained in a web map
Delete SDE feature class features with ArcPyWorking with feature classes from multiple geodatabases in ArcPy?How to Create Feature Layers and Search by Location for all Feature Classes in Geodatabase?How to get a search cursor on a particular version in arcpyArcpy Copy Feature Classes with Overwrite to specific feature datasetsExporting feature class to SQLite database using ArcPy with ArcGIS Pro?Populate several fields only within selected feature classesJoining tables to feature classes in batch using ArcPy?Turning off Feature Classes in ArcGIS Pro using ArcPy?Adding feature class to Map in CURRENT project using ArcPy in ArcGIS Pro?
I am building a stand alone arcpy script, and need to connect to the specific feature classes within a published web map, query/copy from those feature classes, then after some processing update those specific feature classes with new or modified data.
I have a GUID value to the specific web map I need to interact with (this is my only point of entry to the underlying feature classes), but I need to be able to find the database connections to the database and feature classes that make up the web map. The web map was constructed from 3 published web feature layers/feature services, each containing 1-many feature classes, and I ultimately need to obtain the database connection to a specific point feature and line feature, run my script (which makes copies of those feature classes then runs arcpy geo-processing steps-near_analysis, snap, SplitLineAtPoint, AddGeometryAttributes) then need to update/add features back to the respective database and feature classes.
My querying/geo-processing script is already working on hardcoded database connections, but now I need to loop through the various GUIDs I have to different web maps and dynamically connect to variable database connections within the web map (that I have a GUID ID for).
I have found documentation showing how to access webmaps:
from arcgis.gis import GIS
gis = GIS()
web_map = gis.content.get('<GUID value>')#where GUID value is the GUID I have in a list
and then accessing the web feature layers that make up the web map:
web_map_layers = webMap(web_map)
layers = web_map_layers.layers
but printing that out just seems to give me a list of dictionaries, not something that I can assign to a variable and treat as a real feature class within a database or even temporarily in memory.
arcpy esri-geodatabase feature-class feature-layer feature-service
bumped to the homepage by Community♦ 7 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
I am building a stand alone arcpy script, and need to connect to the specific feature classes within a published web map, query/copy from those feature classes, then after some processing update those specific feature classes with new or modified data.
I have a GUID value to the specific web map I need to interact with (this is my only point of entry to the underlying feature classes), but I need to be able to find the database connections to the database and feature classes that make up the web map. The web map was constructed from 3 published web feature layers/feature services, each containing 1-many feature classes, and I ultimately need to obtain the database connection to a specific point feature and line feature, run my script (which makes copies of those feature classes then runs arcpy geo-processing steps-near_analysis, snap, SplitLineAtPoint, AddGeometryAttributes) then need to update/add features back to the respective database and feature classes.
My querying/geo-processing script is already working on hardcoded database connections, but now I need to loop through the various GUIDs I have to different web maps and dynamically connect to variable database connections within the web map (that I have a GUID ID for).
I have found documentation showing how to access webmaps:
from arcgis.gis import GIS
gis = GIS()
web_map = gis.content.get('<GUID value>')#where GUID value is the GUID I have in a list
and then accessing the web feature layers that make up the web map:
web_map_layers = webMap(web_map)
layers = web_map_layers.layers
but printing that out just seems to give me a list of dictionaries, not something that I can assign to a variable and treat as a real feature class within a database or even temporarily in memory.
arcpy esri-geodatabase feature-class feature-layer feature-service
bumped to the homepage by Community♦ 7 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
I am building a stand alone arcpy script, and need to connect to the specific feature classes within a published web map, query/copy from those feature classes, then after some processing update those specific feature classes with new or modified data.
I have a GUID value to the specific web map I need to interact with (this is my only point of entry to the underlying feature classes), but I need to be able to find the database connections to the database and feature classes that make up the web map. The web map was constructed from 3 published web feature layers/feature services, each containing 1-many feature classes, and I ultimately need to obtain the database connection to a specific point feature and line feature, run my script (which makes copies of those feature classes then runs arcpy geo-processing steps-near_analysis, snap, SplitLineAtPoint, AddGeometryAttributes) then need to update/add features back to the respective database and feature classes.
My querying/geo-processing script is already working on hardcoded database connections, but now I need to loop through the various GUIDs I have to different web maps and dynamically connect to variable database connections within the web map (that I have a GUID ID for).
I have found documentation showing how to access webmaps:
from arcgis.gis import GIS
gis = GIS()
web_map = gis.content.get('<GUID value>')#where GUID value is the GUID I have in a list
and then accessing the web feature layers that make up the web map:
web_map_layers = webMap(web_map)
layers = web_map_layers.layers
but printing that out just seems to give me a list of dictionaries, not something that I can assign to a variable and treat as a real feature class within a database or even temporarily in memory.
arcpy esri-geodatabase feature-class feature-layer feature-service
I am building a stand alone arcpy script, and need to connect to the specific feature classes within a published web map, query/copy from those feature classes, then after some processing update those specific feature classes with new or modified data.
I have a GUID value to the specific web map I need to interact with (this is my only point of entry to the underlying feature classes), but I need to be able to find the database connections to the database and feature classes that make up the web map. The web map was constructed from 3 published web feature layers/feature services, each containing 1-many feature classes, and I ultimately need to obtain the database connection to a specific point feature and line feature, run my script (which makes copies of those feature classes then runs arcpy geo-processing steps-near_analysis, snap, SplitLineAtPoint, AddGeometryAttributes) then need to update/add features back to the respective database and feature classes.
My querying/geo-processing script is already working on hardcoded database connections, but now I need to loop through the various GUIDs I have to different web maps and dynamically connect to variable database connections within the web map (that I have a GUID ID for).
I have found documentation showing how to access webmaps:
from arcgis.gis import GIS
gis = GIS()
web_map = gis.content.get('<GUID value>')#where GUID value is the GUID I have in a list
and then accessing the web feature layers that make up the web map:
web_map_layers = webMap(web_map)
layers = web_map_layers.layers
but printing that out just seems to give me a list of dictionaries, not something that I can assign to a variable and treat as a real feature class within a database or even temporarily in memory.
arcpy esri-geodatabase feature-class feature-layer feature-service
arcpy esri-geodatabase feature-class feature-layer feature-service
asked Jan 24 at 17:52
m.Walkerm.Walker
408
408
bumped to the homepage by Community♦ 7 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
bumped to the homepage by Community♦ 7 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I was finally able to get this to work, by taking the WebMap guid ID supplied, and:
- find out the Feature Service of the feature I wanted to copy
- hit the REST end point of that feature service
- copy that feature set down to a feature class.
This then allowed me to run my geo-processing tools, and report my findings. The only thing I have yet to figure out is how to push my updates/additions back to the underlying feature classes in the feature services...
Here is the code that worked for me (with some data/code redacted/changed):
import arcpy
from arcpy import env
import timeit
import uuid
from arcgis.gis import GIS
from arcgis import features
from arcgis.mapping import WebMap
from collections import OrderedDict
import json
import urllib
import http.client
start_time = timeit.default_timer()
#Constant values
SURVEY_DB_WORKSPACE = r'C:Userssurvey_gdb.sde'
#survey table server instance and owner prefix values
SURVEY_DB_INSTANCE_AND_OWNER = 'mydb.dbo.'
GEO_PROC_WORKSPACE = r"C:Usersgeo_proc_gdb.sde"
#geo-proc server instance and owner prefix values
GEO_PROC_DB_INSTANCE_AND_OWNER = 'mydb_gdb.DBO.'
#rest services credentials
USERNAME = 'user'
PASSWORD = 'password'
PORTAL_URL = 'https://mywebsite/portal'
SERVERNAME = "mywebsite"
PORT = ''#if using web adaptor, leave empty (modify tokenURL)
TOKEN_URL = "https://mywebsite/server/admin/generateToken"
def main():
#set environment to the Survey database, loop through surveys table, grab WebMap GUID
workspace = SURVEY_DB_WORKSPACE
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
surveys = SURVEY_DB_INSTANCE_AND_OWNER + 'Surveys'
where_clause = "active = 1"
fields = ['OID@', 'Name', 'Id', 'Progress']
web_map_ids = OrderedDict()
with arcpy.da.SearchCursor(surveys, fields) as cursor:
for row in cursor:
web_map_ids[row[0]] = [row[1], row[2], row[3]]
#change environment to the geo-processing database
workspace = GEO_PROC_WORKSPACE
#connect to db and set point and line features
field = 'state'
lines_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_backup'
points_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'points_backup'
tmp_lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'tmp_lines_split'
lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_split'
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
#Define how to acquire a rest services token
#from https://community.esri.com/thread/83654
def getToken(username, password, serverName, serverPort):
params = urllib.parse.urlencode({'username': USERNAME, 'password': PASSWORD,'client': 'requestip', 'f': 'json'})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
# Connect to URL and post parameters
httpConn = http.client.HTTPSConnection(serverName, serverPort)
httpConn.request("POST", TOKEN_URL, params, headers)
# Read response
response = httpConn.getresponse()
print(response.status)
if (response.status != 200):
httpConn.close()
print("Error while fetching tokens from admin URL. Please check the URL and try again.")
return
else:
data = response.read()
httpConn.close()
# Check that data returned is not an error object
if not assertJsonSuccess(data):
return
# Extract the token from it
token = json.loads(data)
return token['token']
###End getToken function
# A function that checks that the input JSON object is not an error object.
def assertJsonSuccess(data):
obj = json.loads(data)
if 'status' in obj and obj['status'] == "error":
print("Error: JSON object returns an error. " + str(obj))
return False
else:
return True
### End jsonSuccess function
"""
This is the Main loop through WebMap values, processing and reporting back to survey, then continuing
"""
#loop through the survey web map guids for processing-this is where the GUID values come from
current_survey = ''
for k,v in web_map_ids.items():
if v[1] is None:
continue
current_survey = v[0]
#get WebMap
gis = GIS(PORTAL_URL, username=USERNAME, password=PASSWORD)
web_map = gis.content.get(v[1])
web_Map = WebMap(web_map)
web_map_layers = web_Map.layers
#extract the feature service name that contains the Point feature class
num = 0
for item in web_map_layers:
for tag in item:
if tag =='title':
if item[tag] == 'Point':
num = web_map_layers.index(item)
else:
continue
else:
continue
point_url = web_map_layers[num]['url']
#from https://www.esri.com/arcgis-blog/products/arcgis-desktop/analytics/quick-tips-consuming-feature-services-with-geoprocessing/
#Extract Points from feature service to feature class
baseURL = point_url
where = '1=1'
fields = '*'
token = 'getToken(USERNAME, PASSWORD, SERVERNAME, PORT)'
query = "?where={}&outFields={}&returnGeometry=true&f=json&token={}".format(where, fields, token)
# See http://services1.arcgis.com/help/index.html?fsQuery.html for more info on FS-Query
fsURL = baseURL + query
fs = arcpy.FeatureSet()
fs.load(fsURL)
#clean up prior to re-creating backups
if arcpy.Exists(lines_backup):
arcpy.Delete_management(lines_backup)
if arcpy.Exists(points_backup):
arcpy.Delete_management(points_backup)
#copy Points from feature service to feature class, for geo-processing
arcpy.CopyFeatures_management(fs, points_backup)
Once I was able to copy the feature set from the feature service to a feature class, I was able to then run the rest of my geo-processing script. I have not yet been able to push updates/additions back up to those feature classes underlying the feature services though. tackling that now...
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "79"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fgis.stackexchange.com%2fquestions%2f309790%2farcpy-way-to-access-underlying-feature-classes-contained-in-a-web-map%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I was finally able to get this to work, by taking the WebMap guid ID supplied, and:
- find out the Feature Service of the feature I wanted to copy
- hit the REST end point of that feature service
- copy that feature set down to a feature class.
This then allowed me to run my geo-processing tools, and report my findings. The only thing I have yet to figure out is how to push my updates/additions back to the underlying feature classes in the feature services...
Here is the code that worked for me (with some data/code redacted/changed):
import arcpy
from arcpy import env
import timeit
import uuid
from arcgis.gis import GIS
from arcgis import features
from arcgis.mapping import WebMap
from collections import OrderedDict
import json
import urllib
import http.client
start_time = timeit.default_timer()
#Constant values
SURVEY_DB_WORKSPACE = r'C:Userssurvey_gdb.sde'
#survey table server instance and owner prefix values
SURVEY_DB_INSTANCE_AND_OWNER = 'mydb.dbo.'
GEO_PROC_WORKSPACE = r"C:Usersgeo_proc_gdb.sde"
#geo-proc server instance and owner prefix values
GEO_PROC_DB_INSTANCE_AND_OWNER = 'mydb_gdb.DBO.'
#rest services credentials
USERNAME = 'user'
PASSWORD = 'password'
PORTAL_URL = 'https://mywebsite/portal'
SERVERNAME = "mywebsite"
PORT = ''#if using web adaptor, leave empty (modify tokenURL)
TOKEN_URL = "https://mywebsite/server/admin/generateToken"
def main():
#set environment to the Survey database, loop through surveys table, grab WebMap GUID
workspace = SURVEY_DB_WORKSPACE
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
surveys = SURVEY_DB_INSTANCE_AND_OWNER + 'Surveys'
where_clause = "active = 1"
fields = ['OID@', 'Name', 'Id', 'Progress']
web_map_ids = OrderedDict()
with arcpy.da.SearchCursor(surveys, fields) as cursor:
for row in cursor:
web_map_ids[row[0]] = [row[1], row[2], row[3]]
#change environment to the geo-processing database
workspace = GEO_PROC_WORKSPACE
#connect to db and set point and line features
field = 'state'
lines_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_backup'
points_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'points_backup'
tmp_lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'tmp_lines_split'
lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_split'
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
#Define how to acquire a rest services token
#from https://community.esri.com/thread/83654
def getToken(username, password, serverName, serverPort):
params = urllib.parse.urlencode({'username': USERNAME, 'password': PASSWORD,'client': 'requestip', 'f': 'json'})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
# Connect to URL and post parameters
httpConn = http.client.HTTPSConnection(serverName, serverPort)
httpConn.request("POST", TOKEN_URL, params, headers)
# Read response
response = httpConn.getresponse()
print(response.status)
if (response.status != 200):
httpConn.close()
print("Error while fetching tokens from admin URL. Please check the URL and try again.")
return
else:
data = response.read()
httpConn.close()
# Check that data returned is not an error object
if not assertJsonSuccess(data):
return
# Extract the token from it
token = json.loads(data)
return token['token']
###End getToken function
# A function that checks that the input JSON object is not an error object.
def assertJsonSuccess(data):
obj = json.loads(data)
if 'status' in obj and obj['status'] == "error":
print("Error: JSON object returns an error. " + str(obj))
return False
else:
return True
### End jsonSuccess function
"""
This is the Main loop through WebMap values, processing and reporting back to survey, then continuing
"""
#loop through the survey web map guids for processing-this is where the GUID values come from
current_survey = ''
for k,v in web_map_ids.items():
if v[1] is None:
continue
current_survey = v[0]
#get WebMap
gis = GIS(PORTAL_URL, username=USERNAME, password=PASSWORD)
web_map = gis.content.get(v[1])
web_Map = WebMap(web_map)
web_map_layers = web_Map.layers
#extract the feature service name that contains the Point feature class
num = 0
for item in web_map_layers:
for tag in item:
if tag =='title':
if item[tag] == 'Point':
num = web_map_layers.index(item)
else:
continue
else:
continue
point_url = web_map_layers[num]['url']
#from https://www.esri.com/arcgis-blog/products/arcgis-desktop/analytics/quick-tips-consuming-feature-services-with-geoprocessing/
#Extract Points from feature service to feature class
baseURL = point_url
where = '1=1'
fields = '*'
token = 'getToken(USERNAME, PASSWORD, SERVERNAME, PORT)'
query = "?where={}&outFields={}&returnGeometry=true&f=json&token={}".format(where, fields, token)
# See http://services1.arcgis.com/help/index.html?fsQuery.html for more info on FS-Query
fsURL = baseURL + query
fs = arcpy.FeatureSet()
fs.load(fsURL)
#clean up prior to re-creating backups
if arcpy.Exists(lines_backup):
arcpy.Delete_management(lines_backup)
if arcpy.Exists(points_backup):
arcpy.Delete_management(points_backup)
#copy Points from feature service to feature class, for geo-processing
arcpy.CopyFeatures_management(fs, points_backup)
Once I was able to copy the feature set from the feature service to a feature class, I was able to then run the rest of my geo-processing script. I have not yet been able to push updates/additions back up to those feature classes underlying the feature services though. tackling that now...
add a comment |
I was finally able to get this to work, by taking the WebMap guid ID supplied, and:
- find out the Feature Service of the feature I wanted to copy
- hit the REST end point of that feature service
- copy that feature set down to a feature class.
This then allowed me to run my geo-processing tools, and report my findings. The only thing I have yet to figure out is how to push my updates/additions back to the underlying feature classes in the feature services...
Here is the code that worked for me (with some data/code redacted/changed):
import arcpy
from arcpy import env
import timeit
import uuid
from arcgis.gis import GIS
from arcgis import features
from arcgis.mapping import WebMap
from collections import OrderedDict
import json
import urllib
import http.client
start_time = timeit.default_timer()
#Constant values
SURVEY_DB_WORKSPACE = r'C:Userssurvey_gdb.sde'
#survey table server instance and owner prefix values
SURVEY_DB_INSTANCE_AND_OWNER = 'mydb.dbo.'
GEO_PROC_WORKSPACE = r"C:Usersgeo_proc_gdb.sde"
#geo-proc server instance and owner prefix values
GEO_PROC_DB_INSTANCE_AND_OWNER = 'mydb_gdb.DBO.'
#rest services credentials
USERNAME = 'user'
PASSWORD = 'password'
PORTAL_URL = 'https://mywebsite/portal'
SERVERNAME = "mywebsite"
PORT = ''#if using web adaptor, leave empty (modify tokenURL)
TOKEN_URL = "https://mywebsite/server/admin/generateToken"
def main():
#set environment to the Survey database, loop through surveys table, grab WebMap GUID
workspace = SURVEY_DB_WORKSPACE
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
surveys = SURVEY_DB_INSTANCE_AND_OWNER + 'Surveys'
where_clause = "active = 1"
fields = ['OID@', 'Name', 'Id', 'Progress']
web_map_ids = OrderedDict()
with arcpy.da.SearchCursor(surveys, fields) as cursor:
for row in cursor:
web_map_ids[row[0]] = [row[1], row[2], row[3]]
#change environment to the geo-processing database
workspace = GEO_PROC_WORKSPACE
#connect to db and set point and line features
field = 'state'
lines_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_backup'
points_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'points_backup'
tmp_lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'tmp_lines_split'
lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_split'
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
#Define how to acquire a rest services token
#from https://community.esri.com/thread/83654
def getToken(username, password, serverName, serverPort):
params = urllib.parse.urlencode({'username': USERNAME, 'password': PASSWORD,'client': 'requestip', 'f': 'json'})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
# Connect to URL and post parameters
httpConn = http.client.HTTPSConnection(serverName, serverPort)
httpConn.request("POST", TOKEN_URL, params, headers)
# Read response
response = httpConn.getresponse()
print(response.status)
if (response.status != 200):
httpConn.close()
print("Error while fetching tokens from admin URL. Please check the URL and try again.")
return
else:
data = response.read()
httpConn.close()
# Check that data returned is not an error object
if not assertJsonSuccess(data):
return
# Extract the token from it
token = json.loads(data)
return token['token']
###End getToken function
# A function that checks that the input JSON object is not an error object.
def assertJsonSuccess(data):
obj = json.loads(data)
if 'status' in obj and obj['status'] == "error":
print("Error: JSON object returns an error. " + str(obj))
return False
else:
return True
### End jsonSuccess function
"""
This is the Main loop through WebMap values, processing and reporting back to survey, then continuing
"""
#loop through the survey web map guids for processing-this is where the GUID values come from
current_survey = ''
for k,v in web_map_ids.items():
if v[1] is None:
continue
current_survey = v[0]
#get WebMap
gis = GIS(PORTAL_URL, username=USERNAME, password=PASSWORD)
web_map = gis.content.get(v[1])
web_Map = WebMap(web_map)
web_map_layers = web_Map.layers
#extract the feature service name that contains the Point feature class
num = 0
for item in web_map_layers:
for tag in item:
if tag =='title':
if item[tag] == 'Point':
num = web_map_layers.index(item)
else:
continue
else:
continue
point_url = web_map_layers[num]['url']
#from https://www.esri.com/arcgis-blog/products/arcgis-desktop/analytics/quick-tips-consuming-feature-services-with-geoprocessing/
#Extract Points from feature service to feature class
baseURL = point_url
where = '1=1'
fields = '*'
token = 'getToken(USERNAME, PASSWORD, SERVERNAME, PORT)'
query = "?where={}&outFields={}&returnGeometry=true&f=json&token={}".format(where, fields, token)
# See http://services1.arcgis.com/help/index.html?fsQuery.html for more info on FS-Query
fsURL = baseURL + query
fs = arcpy.FeatureSet()
fs.load(fsURL)
#clean up prior to re-creating backups
if arcpy.Exists(lines_backup):
arcpy.Delete_management(lines_backup)
if arcpy.Exists(points_backup):
arcpy.Delete_management(points_backup)
#copy Points from feature service to feature class, for geo-processing
arcpy.CopyFeatures_management(fs, points_backup)
Once I was able to copy the feature set from the feature service to a feature class, I was able to then run the rest of my geo-processing script. I have not yet been able to push updates/additions back up to those feature classes underlying the feature services though. tackling that now...
add a comment |
I was finally able to get this to work, by taking the WebMap guid ID supplied, and:
- find out the Feature Service of the feature I wanted to copy
- hit the REST end point of that feature service
- copy that feature set down to a feature class.
This then allowed me to run my geo-processing tools, and report my findings. The only thing I have yet to figure out is how to push my updates/additions back to the underlying feature classes in the feature services...
Here is the code that worked for me (with some data/code redacted/changed):
import arcpy
from arcpy import env
import timeit
import uuid
from arcgis.gis import GIS
from arcgis import features
from arcgis.mapping import WebMap
from collections import OrderedDict
import json
import urllib
import http.client
start_time = timeit.default_timer()
#Constant values
SURVEY_DB_WORKSPACE = r'C:Userssurvey_gdb.sde'
#survey table server instance and owner prefix values
SURVEY_DB_INSTANCE_AND_OWNER = 'mydb.dbo.'
GEO_PROC_WORKSPACE = r"C:Usersgeo_proc_gdb.sde"
#geo-proc server instance and owner prefix values
GEO_PROC_DB_INSTANCE_AND_OWNER = 'mydb_gdb.DBO.'
#rest services credentials
USERNAME = 'user'
PASSWORD = 'password'
PORTAL_URL = 'https://mywebsite/portal'
SERVERNAME = "mywebsite"
PORT = ''#if using web adaptor, leave empty (modify tokenURL)
TOKEN_URL = "https://mywebsite/server/admin/generateToken"
def main():
#set environment to the Survey database, loop through surveys table, grab WebMap GUID
workspace = SURVEY_DB_WORKSPACE
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
surveys = SURVEY_DB_INSTANCE_AND_OWNER + 'Surveys'
where_clause = "active = 1"
fields = ['OID@', 'Name', 'Id', 'Progress']
web_map_ids = OrderedDict()
with arcpy.da.SearchCursor(surveys, fields) as cursor:
for row in cursor:
web_map_ids[row[0]] = [row[1], row[2], row[3]]
#change environment to the geo-processing database
workspace = GEO_PROC_WORKSPACE
#connect to db and set point and line features
field = 'state'
lines_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_backup'
points_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'points_backup'
tmp_lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'tmp_lines_split'
lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_split'
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
#Define how to acquire a rest services token
#from https://community.esri.com/thread/83654
def getToken(username, password, serverName, serverPort):
params = urllib.parse.urlencode({'username': USERNAME, 'password': PASSWORD,'client': 'requestip', 'f': 'json'})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
# Connect to URL and post parameters
httpConn = http.client.HTTPSConnection(serverName, serverPort)
httpConn.request("POST", TOKEN_URL, params, headers)
# Read response
response = httpConn.getresponse()
print(response.status)
if (response.status != 200):
httpConn.close()
print("Error while fetching tokens from admin URL. Please check the URL and try again.")
return
else:
data = response.read()
httpConn.close()
# Check that data returned is not an error object
if not assertJsonSuccess(data):
return
# Extract the token from it
token = json.loads(data)
return token['token']
###End getToken function
# A function that checks that the input JSON object is not an error object.
def assertJsonSuccess(data):
obj = json.loads(data)
if 'status' in obj and obj['status'] == "error":
print("Error: JSON object returns an error. " + str(obj))
return False
else:
return True
### End jsonSuccess function
"""
This is the Main loop through WebMap values, processing and reporting back to survey, then continuing
"""
#loop through the survey web map guids for processing-this is where the GUID values come from
current_survey = ''
for k,v in web_map_ids.items():
if v[1] is None:
continue
current_survey = v[0]
#get WebMap
gis = GIS(PORTAL_URL, username=USERNAME, password=PASSWORD)
web_map = gis.content.get(v[1])
web_Map = WebMap(web_map)
web_map_layers = web_Map.layers
#extract the feature service name that contains the Point feature class
num = 0
for item in web_map_layers:
for tag in item:
if tag =='title':
if item[tag] == 'Point':
num = web_map_layers.index(item)
else:
continue
else:
continue
point_url = web_map_layers[num]['url']
#from https://www.esri.com/arcgis-blog/products/arcgis-desktop/analytics/quick-tips-consuming-feature-services-with-geoprocessing/
#Extract Points from feature service to feature class
baseURL = point_url
where = '1=1'
fields = '*'
token = 'getToken(USERNAME, PASSWORD, SERVERNAME, PORT)'
query = "?where={}&outFields={}&returnGeometry=true&f=json&token={}".format(where, fields, token)
# See http://services1.arcgis.com/help/index.html?fsQuery.html for more info on FS-Query
fsURL = baseURL + query
fs = arcpy.FeatureSet()
fs.load(fsURL)
#clean up prior to re-creating backups
if arcpy.Exists(lines_backup):
arcpy.Delete_management(lines_backup)
if arcpy.Exists(points_backup):
arcpy.Delete_management(points_backup)
#copy Points from feature service to feature class, for geo-processing
arcpy.CopyFeatures_management(fs, points_backup)
Once I was able to copy the feature set from the feature service to a feature class, I was able to then run the rest of my geo-processing script. I have not yet been able to push updates/additions back up to those feature classes underlying the feature services though. tackling that now...
I was finally able to get this to work, by taking the WebMap guid ID supplied, and:
- find out the Feature Service of the feature I wanted to copy
- hit the REST end point of that feature service
- copy that feature set down to a feature class.
This then allowed me to run my geo-processing tools, and report my findings. The only thing I have yet to figure out is how to push my updates/additions back to the underlying feature classes in the feature services...
Here is the code that worked for me (with some data/code redacted/changed):
import arcpy
from arcpy import env
import timeit
import uuid
from arcgis.gis import GIS
from arcgis import features
from arcgis.mapping import WebMap
from collections import OrderedDict
import json
import urllib
import http.client
start_time = timeit.default_timer()
#Constant values
SURVEY_DB_WORKSPACE = r'C:Userssurvey_gdb.sde'
#survey table server instance and owner prefix values
SURVEY_DB_INSTANCE_AND_OWNER = 'mydb.dbo.'
GEO_PROC_WORKSPACE = r"C:Usersgeo_proc_gdb.sde"
#geo-proc server instance and owner prefix values
GEO_PROC_DB_INSTANCE_AND_OWNER = 'mydb_gdb.DBO.'
#rest services credentials
USERNAME = 'user'
PASSWORD = 'password'
PORTAL_URL = 'https://mywebsite/portal'
SERVERNAME = "mywebsite"
PORT = ''#if using web adaptor, leave empty (modify tokenURL)
TOKEN_URL = "https://mywebsite/server/admin/generateToken"
def main():
#set environment to the Survey database, loop through surveys table, grab WebMap GUID
workspace = SURVEY_DB_WORKSPACE
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
surveys = SURVEY_DB_INSTANCE_AND_OWNER + 'Surveys'
where_clause = "active = 1"
fields = ['OID@', 'Name', 'Id', 'Progress']
web_map_ids = OrderedDict()
with arcpy.da.SearchCursor(surveys, fields) as cursor:
for row in cursor:
web_map_ids[row[0]] = [row[1], row[2], row[3]]
#change environment to the geo-processing database
workspace = GEO_PROC_WORKSPACE
#connect to db and set point and line features
field = 'state'
lines_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_backup'
points_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'points_backup'
tmp_lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'tmp_lines_split'
lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_split'
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
#Define how to acquire a rest services token
#from https://community.esri.com/thread/83654
def getToken(username, password, serverName, serverPort):
params = urllib.parse.urlencode({'username': USERNAME, 'password': PASSWORD,'client': 'requestip', 'f': 'json'})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
# Connect to URL and post parameters
httpConn = http.client.HTTPSConnection(serverName, serverPort)
httpConn.request("POST", TOKEN_URL, params, headers)
# Read response
response = httpConn.getresponse()
print(response.status)
if (response.status != 200):
httpConn.close()
print("Error while fetching tokens from admin URL. Please check the URL and try again.")
return
else:
data = response.read()
httpConn.close()
# Check that data returned is not an error object
if not assertJsonSuccess(data):
return
# Extract the token from it
token = json.loads(data)
return token['token']
###End getToken function
# A function that checks that the input JSON object is not an error object.
def assertJsonSuccess(data):
obj = json.loads(data)
if 'status' in obj and obj['status'] == "error":
print("Error: JSON object returns an error. " + str(obj))
return False
else:
return True
### End jsonSuccess function
"""
This is the Main loop through WebMap values, processing and reporting back to survey, then continuing
"""
#loop through the survey web map guids for processing-this is where the GUID values come from
current_survey = ''
for k,v in web_map_ids.items():
if v[1] is None:
continue
current_survey = v[0]
#get WebMap
gis = GIS(PORTAL_URL, username=USERNAME, password=PASSWORD)
web_map = gis.content.get(v[1])
web_Map = WebMap(web_map)
web_map_layers = web_Map.layers
#extract the feature service name that contains the Point feature class
num = 0
for item in web_map_layers:
for tag in item:
if tag =='title':
if item[tag] == 'Point':
num = web_map_layers.index(item)
else:
continue
else:
continue
point_url = web_map_layers[num]['url']
#from https://www.esri.com/arcgis-blog/products/arcgis-desktop/analytics/quick-tips-consuming-feature-services-with-geoprocessing/
#Extract Points from feature service to feature class
baseURL = point_url
where = '1=1'
fields = '*'
token = 'getToken(USERNAME, PASSWORD, SERVERNAME, PORT)'
query = "?where={}&outFields={}&returnGeometry=true&f=json&token={}".format(where, fields, token)
# See http://services1.arcgis.com/help/index.html?fsQuery.html for more info on FS-Query
fsURL = baseURL + query
fs = arcpy.FeatureSet()
fs.load(fsURL)
#clean up prior to re-creating backups
if arcpy.Exists(lines_backup):
arcpy.Delete_management(lines_backup)
if arcpy.Exists(points_backup):
arcpy.Delete_management(points_backup)
#copy Points from feature service to feature class, for geo-processing
arcpy.CopyFeatures_management(fs, points_backup)
Once I was able to copy the feature set from the feature service to a feature class, I was able to then run the rest of my geo-processing script. I have not yet been able to push updates/additions back up to those feature classes underlying the feature services though. tackling that now...
answered Jan 26 at 3:06
m.Walkerm.Walker
408
408
add a comment |
add a comment |
Thanks for contributing an answer to Geographic Information Systems Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fgis.stackexchange.com%2fquestions%2f309790%2farcpy-way-to-access-underlying-feature-classes-contained-in-a-web-map%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown