-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pull request to add Add_Geomark_URLs to gis-pantry/tools (#178)
* Uploaded files Uploaded code files and toolbox files for Add Geomark URLs tools * Uploaded readme template Uploaded readme template to be edited in github web interface * Delete tools/Add_Geomark_URLs/readme.md * Create readme.md * Update readme.md Updated readme.md with text * Update readme.md
- Loading branch information
1 parent
b5568df
commit 77347d2
Showing
5 changed files
with
236 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
100 changes: 100 additions & 0 deletions
100
tools/Add_Geomark_URLs/ArcGISDesktop/add_geomark_py2.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
r""" | ||
Original Author: [email protected] (FIRB) | ||
Created on: | ||
2024-08-13 | ||
Purpose: | ||
This script creates Geomark URLs for each feature in an input dataset, and | ||
writes them to a new field named Geomark_URL. It can be run at the command | ||
prompt on a system with ArcGIS Pro installed, or directly in ArcGIS Desktop | ||
10.x in a script tool named Add_Geomark_URL in a toolbox named | ||
Add_Geomark_URL.tbx. | ||
Usage: | ||
add_geomark_py2.py lyr | ||
Positional Arguments: | ||
lyr Input layer | ||
Requirements: | ||
ArcGIS Pro | ||
Optional Arguments: | ||
-h, --help show this help message and exit | ||
-l, --level log level messages to display; Default: 20 - INFO | ||
-ld, --log_dir path to directory for output log file | ||
Example Input: | ||
X:\fullpath\add_geomark_py2.py Y:\fullpath\lyr | ||
History | ||
2024-08-13 (JK): Created script. | ||
""" | ||
|
||
import arcpy, urllib2, time, sys | ||
from urllib import urlencode | ||
|
||
def add_geomark_url(in_fc): | ||
|
||
# Get the spatial reference of the input dataset | ||
srid = arcpy.Describe(in_fc).spatialReference.factoryCode | ||
arcpy.AddMessage(time.strftime("%Y-%m-%d %H:%M:%S : ") + "Spatial reference code of input dataset: " + str(srid)) | ||
|
||
# Add Geomark_URL field if it doesn't already exist | ||
flist = [f.name for f in arcpy.ListFields(in_fc)] | ||
if "Geomark_URL" not in flist: | ||
try: | ||
arcpy.AddField_management(in_table=in_fc, field_name="Geomark_URL", field_type="TEXT", field_length=100) | ||
except: | ||
arcpy.AddError(time.strftime("%Y-%m-%d %H:%M:%S : ") + "Unable to add field to input dataset. Exiting.") | ||
sys.exit() | ||
arcpy.AddMessage(time.strftime("%Y-%m-%d %H:%M:%S : ") + "Added Geomark_URL field to input layer") | ||
else: | ||
arcpy.AddMessage(time.strftime("%Y-%m-%d %H:%M:%S : ") + "Geomark_URL field already exists in input layer") | ||
|
||
# Read each record, send request to create Geomark URL, write the returned URL to the Geomark_URL field | ||
row_total = int(arcpy.GetCount_management(in_fc).getOutput(0)) | ||
read_count = 0 | ||
update_count = 0 | ||
arcpy.AddMessage(time.strftime("%Y-%m-%d %H:%M:%S : ") + "Processing " + str(row_total) + " feature(s) of input " | ||
"dataset") | ||
with arcpy.da.UpdateCursor(in_fc, ["Geomark_URL", "SHAPE@"]) as cursor: | ||
for row in cursor: | ||
read_count += 1 | ||
exist_url = row[0] | ||
if exist_url is None: | ||
geom = row[1] | ||
if geom is None: | ||
row[0] = "Null geometry" | ||
else: | ||
geom_wkt = geom.WKT | ||
post_url = "https://apps.gov.bc.ca/pub/geomark/geomarks/new" | ||
payload = {"bufferSegments": 8, "body": geom_wkt, "bufferMetres": 0, "callback": None, | ||
"failureRedirectUrl": None, "bufferJoin": "ROUND", "bufferMitreLimit": 5, | ||
"bufferCap": "ROUND", "redirectUrl": None, "resultFormat": None, "format": "wkt", | ||
"srid": srid, "allowOverlap": "false"} | ||
post = urlencode(payload) | ||
req = urllib2.Request(post_url, post) | ||
response = urllib2.urlopen(req) | ||
if response.code == 200: | ||
r = response.read() | ||
out_url = r.split('"url":"')[1].split('"')[0] | ||
if out_url == "https://apps.gov.bc.ca/pub/geomark/geomarks/new": | ||
row[0] = "Could not create Geomark URL for this geometry" | ||
else: | ||
row[0] = out_url | ||
update_count += 1 | ||
else: | ||
row[0] = "Error response code " + str(response.code) | ||
cursor.updateRow(row) | ||
|
||
if read_count % 10 == 0 or read_count == row_total: | ||
arcpy.AddMessage(time.strftime("%Y-%m-%d %H:%M:%S : ") + "Processed " + str(read_count) + " of " + | ||
str(row_total) + " feature(s) and added Geomark URL to " + str(update_count) + | ||
" feature(s)") | ||
|
||
if __name__ == "__main__": | ||
in_fc = arcpy.GetParameterAsText(0) | ||
add_geomark_url(in_fc) |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
r""" | ||
Original Author: [email protected] (FIRB) | ||
Created on: | ||
2024-08-12 | ||
Purpose: | ||
This script creates Geomark URLs for each feature in an input dataset, and | ||
writes them to a new field named Geomark_URL. It can be run at the command | ||
prompt on a system with ArcGIS Pro installed, or directly in ArcGIS Pro in a | ||
script tool named Add_Geomark_URL in a toolbox named Add_Geomark_URL.atbx. | ||
Usage: | ||
add_geomark_py3.py lyr | ||
Positional Arguments: | ||
lyr Input layer | ||
Requirements: | ||
ArcGIS Pro | ||
Example Input: | ||
X:\fullpath\add_geomark_py3.py Y:\fullpath\lyr | ||
History | ||
2024-08-12 (JK): Created script. | ||
""" | ||
|
||
import arcpy, requests, time | ||
|
||
def add_geomark_url(in_fc): | ||
|
||
# Get the spatial reference of the input dataset | ||
srid = arcpy.da.Describe(in_fc)["spatialReference"].factoryCode | ||
arcpy.AddMessage(time.strftime('%Y-%m-%d %H:%M:%S : ') + f"Spatial reference code of input dataset: {srid}") | ||
|
||
# Add Geomark_URL field if it doesn't already exist | ||
flist = [f.name for f in arcpy.ListFields(in_fc)] | ||
if "Geomark_URL" not in flist: | ||
arcpy.management.AddField(in_table=in_fc, field_name="Geomark_URL", field_type="TEXT", field_length=100) | ||
arcpy.AddMessage(time.strftime('%Y-%m-%d %H:%M:%S : ') + "Added Geomark_URL field to input layer") | ||
else: | ||
arcpy.AddMessage(time.strftime('%Y-%m-%d %H:%M:%S : ') + "Geomark_URL field already exists in input layer") | ||
|
||
# Read each record, send request to create Geomark URL, write the returned URL to the Geomark_URL field | ||
row_total = int(arcpy.GetCount_management(in_fc).getOutput(0)) | ||
read_count = 0 | ||
update_count = 0 | ||
arcpy.AddMessage(time.strftime('%Y-%m-%d %H:%M:%S : ') + f"Processing {row_total} feature(s) of input dataset") | ||
session = requests.Session() | ||
with arcpy.da.UpdateCursor(in_fc, ["Geomark_URL", "SHAPE@"]) as cursor: | ||
for row in cursor: | ||
read_count += 1 | ||
exist_url = row[0] | ||
if exist_url is None: | ||
geom = row[1] | ||
if geom is None: | ||
row[0] = "Null geometry" | ||
else: | ||
geom_wkt = geom.WKT | ||
post_url = "https://apps.gov.bc.ca/pub/geomark/geomarks/new" | ||
payload = {"bufferSegments": 8, "body": geom_wkt, "bufferMetres": None, "callback": None, | ||
"failureRedirectUrl": None, "bufferJoin": "ROUND", "bufferMitreLimit": 5, | ||
"bufferCap": "ROUND", "redirectUrl": None, "resultFormat": None, "format": "wkt", | ||
"srid": srid, "allowOverlap": "false"} | ||
r = session.post(post_url, data=payload, timeout=5) | ||
if r.status_code == 200: | ||
out_url = r.url | ||
if out_url == "https://apps.gov.bc.ca/pub/geomark/geomarks/new": | ||
row[0] = "Could not create Geomark URL for this geometry" | ||
else: | ||
row[0] = out_url | ||
update_count += 1 | ||
cursor.updateRow(row) | ||
|
||
if read_count % 10 == 0 or read_count == row_total: | ||
arcpy.AddMessage(time.strftime('%Y-%m-%d %H:%M:%S : ') + f"Processed {read_count} of {row_total} " | ||
f"feature(s) and added Geomark URL to {update_count} feature(s)") | ||
|
||
if __name__ == "__main__": | ||
in_fc = arcpy.GetParameterAsText(0) | ||
add_geomark_url(in_fc) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Name | ||
|
||
Add_Geomark_URLs | ||
|
||
# Author | ||
|
||
Jeff Kruys, [email protected], Spatial Data Analyst, Forest Investment and Reporting Branch, Ministry of Forests | ||
|
||
# Description | ||
|
||
The Geomark Web Service takes a feature geometry as input and assigns it a unique URL. This URL can then be sent to another party as a representation of the geometry. | ||
|
||
This script tool will add a field named Geomark_URL to a spatial dataset that you select (FGDB feature class, shapefile etc.) and populate the field with a Geomark URL for each feature. There is one tool designed to work in ArcGIS Desktop 10.x (ArcCatalog or ArcMap), and another tool designed to work within ArcGIS Pro 3.x. | ||
|
||
# Usage | ||
|
||
To use the tool in ArcGIS Desktop, download the two files in the ArcGISDesktop folder above, and save them together in a folder on your local drive or a network drive that you have write access to. In ArcMap, open the Catalog pane (in the Windows menu and select Catalog), browse to the folder where you saved the files, and expand the toolbox item named Add_Geomark_URLs_ArcGISDesktop.tbx. You should see a script tool named Add Geomark URL. Double-click this tool to run it. You will be prompted to select a map layer; select one and click OK to run. | ||
|
||
To use the tool in ArcGIS Pro, download the file Add_Geomark_URLs_ArcGISPro.atbx in the ArcGISPro folder above, and save it in a folder on your local drive or a network drive that you have write access to. (This file has the Python code embedded in it, so you do not need to download the other file, add_geomark_py3.py - it is only provided for reference.) In an ArcGIS Pro project, in the Catalog pane under the Project tab, connect to the folder where you saved the file, then browse to that folder and expand the file. You should see a script tool named Add_Geomark_URLs. Double-click that tool to start it. You will be prompted to select a map layer; select one and click OK to run. | ||
|
||
After running, if no error messages are received, open the attribute table of the layer you specified (or if you already had it open, close it and open it again). You should see a newly-added field named Geomark_URL and it should contain a URL for each feature. | ||
|
||
If a feature has null geometry, the field will contain the text "Null geometry" instead of a URL. If any other problem occurred, you may see the text "Could not create Geomark URL for this geometry"; if you see this in the output, please contact the author. | ||
|
||
# Dependencies/Requirements/Environments | ||
|
||
These scripts have been tested in the GTS desktop environments named "Kamloops Desktop - Geospatial" (with ArcGIS Pro 3.2.2) and "Kamloops Desktop - ArcGIS 10-8" (with ArcGIS Desktop 10.8). | ||
|
||
Executing the tool in the ArcGIS Pro environment requires the Python "requests" module, which should have been installed by default with any installation of ArcGIS Pro and Python 3.x. | ||
|
||
Executing the tool in the ArcGIS Desktop environment requires the Python "urllib" and "urllib2" modules, which should have been installed by default with any installation of ArcGIS Desktop 10.8 and Python 2.x. | ||
|
||
If you receive an error such as "ImportError: No module named urllib" when running either of these tools, please contact the author. | ||
|
||
# Known Bugs/Limitations | ||
|
||
This tool is intended to make it easier to generate Geomark URLs more quickly than uploading individual spatial data files for individual features to the Geomark Web Service. | ||
|
||
The ArcGIS Desktop version of the tool runs quickly, creating 10 Geomark URLs in a few seconds. The ArcGIS Pro version of the tool takes a little longer to run - 10 URLs in about 30 seconds. | ||
|
||
Both tools are only intended to be used on datasets with small numbers of records - in the hundreds at most. | ||
|
||
# Credits | ||
|
||
Thanks to the developers of the Geomark Web Service. | ||
|
||
# Update Log | ||
|
||
2024-08-20 (Jeff Kruys): Tools uploaded to GitHub. | ||
|
||
2024-08-13 (Jeff Kruys): Tool completed and tested in ArcGIS Desktop 10.8. | ||
|
||
2024-08-12 (Jeff Kruys): Tool completed and tested in ArcGIS Pro 3.2.2. |