Select to view content in your preferred language

Welcome to the Landscape Layers forum

16484
39
07-05-2013 10:46 AM
CharlieFrye
Esri Contributor

Welcome to the Landscape Maps and Data forum. This forum is for you to post questions and provide ideas for the ArcGIS for Landscape (beta).  

About the Landscape Analysis Layers

These layers are available for use now!  Visit the Landscape Layers Group on ArcGIS.com to learn more.

Feedback

Your feedback matters!  What layers do you find most useful?  How are you using them? Did you use any geoprocessing tools with these services and what was your experience? If you want to let us know, post your feedback here on this forum. Please let us know too, if you have issues or are experiencing problems with any of the layers.  We cannot wait to hear from you!

Tags (2)
39 Replies
GregConiglio
Regular Contributor

Thanks Charlie!  I spent some time getting the code streamlined (a lot of unused code, and duplicate variables as you noted).  It worked a few time!!  it is back to the same error and I am at an impasse why.  When it was working for you, did you request JSON as the output?  THat seems to be an issue.  The script fails with the "Cannot load" error still, presumably because of a lack of proper response / error.  I do these steps:

1. Run the code Ipasted below).  I get the standard error "RuntimeError: RecordSetObject: Cannot open table for Load"

2. In my python output I print the URL we use.  Example here.  I copy and paste this into a browser

http://landscape1.arcgis.com/arcgis/rest/services/USA_Roads/MapServer/0/query?returnGeometry=true&f=...

{"error":{"code":498,"message":"Invalid Token","details":[]}} is the result in the browser.

3. if I remove the "&f=json" argument on the URL, I get a different result:  I am redirected to the ESRI Web API Rest Login Page (which redirects using a URL-safe version of my URL).  It's a little odd because the token argument is in the URL, but I from here I can copy the token string (the same one from above) into my text box and ESRI accepts it.

4. If I repeat step 2 and paste into the same browser instance, the desired JSON result is returned! (Example- {"displayFieldName":"fullname","fieldAliases":{"fullname":"Full Name"},"geometryType":"esriGeometryPolyline","spatialReference":{"wkid":102100,"latestWkid":3857},"fields":[{"name":"fullname","type":"esriFieldTypeString","alias":"Full Name","length":100}],"features":[{"attributes":{"fullname":"New York State Throughway "},"geometry":{"paths":[[[-8734554.8257999998,5309850.4296000004],[-8734553.2673000004,5309851.1904999986],[-8733750.6537999995,5310086.1526999995],[-8732985.3322999999,5310311.2289000005],[-8732888.8182999995,5310339.3828999996],[-8732505.6566000003,5310451.6950000003],[-8731923.9010000005,5310622.7531000003],[-8731833.7322000004,5310648.0164000019],[-8731491.5361000001,5310749.9833000004],[-8731394.4655000009,5310777.3775999993],[-8731240.3992999997,5310823.1871000007],[-8731130.6382999998,5310862.6048000008],[-8731041.6940000001,5310900.0442000031],[-8730938.1668999996,5310948.8981999978],[-8730887.9617999997,5310974.3144999966],[-8730830.9661999997,5311006.5797000006],[-8730806.3646000009,5311020.5816000029],[-8730713.7467999998,5311076.7415999994],[-8730643.0589000005,5311122.7048000023],[-8730529.2904000003,5311207.3263999969],[-8730500.2359999996,5311230.6127000004],[-8730472.4060999993,5311253.1379999965],[-8730182.3074999992,5311481.1340999976],[-8730059.2994999997,5311581.1314999983],[-8729903.8975000009,5311703.1997999996],[-8729871.1695000008,5311728.9226000011],[-8729773.2083999999,5311802.2863000035],[-8729771.9838999994,5311803.1996000037],[-8729645.1909999996,5311904.5702999979],[-8729389.2675000001,5312105.945100002],[-8729340.0643000007,5312143.6938000023],[-8729217.5014999993,5312239.740699999],[-8729133.0099999998,5312310.5208000019],[-8729054.0844999999,5312372.1683000028],[-8728857.0490000006,5312522.5596999973],[-8728842.2434999999,5312533.9760999978],[-8728833.0040000007,5312540.9782000035],[-8728831.000 ..... )

CODE is below.  A few thoughts...

* Could there be a specific issue with the service retruning JSON results? Charlie did you request JSON when it worked?

* Do I need to do more to make the request URL safe?

* Does the same page handle token requests from all *.esri.com domains?  Should I be requesting the token from a different ESRI REST GenerateToken page if there are more than one?

THANKS!!!!!

# Originally based on script from Charlie Frye - ESRI - 12-8-2015

# Import python modules

import arcpy

import re

import copy

import os, sys

from arcpy import env

# For Http calls

import httplib, urllib, json

#Globals

refURL = 'www.arcgis.com'

# A function to generate a token given username, password and the adminURL.

def getToken(username, password, serverName, serverPort):

    # Token URL is typically http://server[:port]/arcgis/admin/generateToken

    print "entering getToken"

    tokenURL = "/sharing/rest/generateToken"

    params = urllib.urlencode({'username': username, 'password': password, 'client': 'referer','referer': refURL, 'expiration':'600','f': 'json'})

    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain",'referer': refURL}

  # Connect to URL and post parameters

    if serverPort == "":

        httpConn = httplib.HTTPSConnection(serverName)

    else:

        httpConn = httplib.HTTPConnection(serverName, serverPort)

    print "request" + tokenURL + "/" + str(params) + "/" + str(headers)

    httpConn.request("POST", tokenURL, params, headers)

    print "request complete"

        # Read response

    response = httpConn.getresponse()

    if (response.status != 200):

        httpConn.close()

        FailType = 'Failed getting token; check connection and credentials'

        print "Error while fetching tokens from admin URL. Please check the URL and try again."

        return

    else:

        data = response.read()

        httpConn.close()

        print "response:" + data

        # Check that data returned is not an error object

        if not assertJsonSuccess(data):

            return

        # Extract the token from it

        token = json.loads(data)

        print "TOKEN SUCCESS"

        return token['token']

    # 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

scratchWkspc = arcpy.env.scratchGDB  #Local Processing Environment

arcpy.env.overwriteOutput = True

serverPort = ""

#Get token via function

tokenString = (getToken("XXXX","XXXXX","www.arcgis.com",serverPort)).encode('ascii','ignore')

print

print "GOT TOKEN STRING"

print tokenString

print

# Get the input feature service and make a feature set, which is what GP tools can use as input

#i#nputField = "OBJECTID"

#where = '1=1'

fsURL = "http://landscape1.arcgis.com/arcgis/rest/services/USA_Roads/MapServer/0/query?returnGeometry=true&f=..."+tokenString

print fsURL

print

# ###### Make the 'Feature Class' from the Service

inputSupplyFC = arcpy.FeatureSet()

inputSupplyFC.load(fsURL)

inputSupplyFC.save(r"L:\temp\greg2.shp")

0 Kudos
CharlieFrye
Esri Contributor

Hi Greg,

I am able to reproduce what you've described. I recalled that when I was originally writing this script, it was important not to set the referer to an actual URL, and than any string, like "arcgis" would instead work.

That no longer seems to be the case, I'll need to investigate that. 

On your questions:

* Could there be a specific issue with the service retruning JSON results? Charlie did you request JSON when it worked?  I've always used JSON for this, though I've tried HTML to see what it looks like (not so parse-able), and so it's rather strange that it allowed the sequence you found.  The reason it works is that once the token is entered in step 3, the browser has cached it.

* Do I need to do more to make the request URL safe?  I'm not sure, as I'm not a web programmer ant not familiar with the concept.

* Does the same page handle token requests from all *.esri.com domains?  Should I be requesting the token from a different ESRI REST GenerateToken page if there are more than one?  No, each ArcGIS Server can be configured to authenticate, and when so the portal, e.g., www.arcgis.com is entered into the server's configuration.

Charlie

0 Kudos
CharlieFrye
Esri Contributor

We verified there is no bug in the URL--though it's a little confusing because the browser uses a different refURL in it's header, and that's why pasting the URL into the browser fails. 

I was able to use Fiddler's Composer, where I could specify the header to match the code, and that works.

The real problem looks to be in the FeatureSet.load() method, and I'll need to check on that next.

0 Kudos
GregConiglio
Regular Contributor

Thanks Charlie -- oh Fiddler, I didn't think of that!  Keep me posted on the load method. That makes sense as I noted twice it DID work .. and then failed after re-running after what I believe were no additional changes in the code

Your help with this is extremely appreciated Charlie!  Happy Holidays!!

0 Kudos
GregConiglio
Regular Contributor

Well just for fun, I tried out the URL in Fiddler Composer to see what happens here.  Oddly, in this case I reproduced the same behavior as we saw in the browser.

Could there be a difference in our organizational accounts?  I could PM mine to you if you wanted to try it...

Or, I am skipping some very simple step?   (screen shots with and without f=json argument)

Thanks again!!!fiddler1.jpgfiddler2.jpg

0 Kudos
CharlieFrye
Esri Contributor

We spent time, yesterday, doing the same, and deduced that the only difference is in the Post request's header, and the refURL was the difference--the same refURL that was in the request to get the token must be used when supplying the token for another request. We proved it by using Fiddler's Composer tab to send the request using the header information used in the Python script, and that worked. The browser sends a request where the header contains a different refURL.

So, effectively, we eliminated the REST API as the cause.  Now we are looking that the FeatureSet.Load() method, which we have found works when using a service that does not require authentication, but does not work when authentication is required (it used to work).

0 Kudos
GregConiglio
Regular Contributor

Hi Charlie!  I hope everyone at ESRI had a great break, Holiday and New Year!! Wondering if there was any more progress, re: "FeatureSet.Load()".  Thanks!!!!

0 Kudos
CharlieFrye
Esri Contributor

I just verified this with the development team, and they reproduced it, and are logging a bug report.  I'll follow up when I've got more information. 

In the meantime, my mind has blanked and it would be good to get back to learning what you originally needed, and let's see if we can get you that data via another means.

Charlie

0 Kudos
GregConiglio
Regular Contributor

Thanks, Charlie!  I might never have originally explained!  I am involved in environmental constraints studies in various areas around the US.  Sometimes they have a short turnaround.  A lot of needed layers are in your Landscape layers.   A lot of the upfront time is spent just gatherign data from the involved municpalities.

I am testing out a script where I can pass in a polygon and data for that polygon is retrieved from your REST service using the script mentioned above  (based on your original but really pared down cause what I would need is not as detailed)

Hope that helps!

0 Kudos
MathewGaskin
New Contributor

Is there a way to add a "gmap" as a layer? Looking to add a soil map layer that contains more information that the SSURGO soil map layer readily available in ArcGIS. The link to the soil map "gmap" is: SoilWeb: An Online Soil Survey Browser | California Soil Resource Lab 

It has the soil types layered with a map unit and is easier to utilize than the unlabeled SSURGO map layer.

0 Kudos