Skip to content

Commit

Permalink
Pull request to add Add_Geomark_URLs to gis-pantry/tools (#178)
Browse files Browse the repository at this point in the history
* 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
jkruys-bcgov authored Sep 4, 2024
1 parent b5568df commit 77347d2
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 0 deletions.
Binary file not shown.
100 changes: 100 additions & 0 deletions tools/Add_Geomark_URLs/ArcGISDesktop/add_geomark_py2.py
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.
83 changes: 83 additions & 0 deletions tools/Add_Geomark_URLs/ArcGISPro/add_geomark_py3.py
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)
53 changes: 53 additions & 0 deletions tools/Add_Geomark_URLs/readme.md
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.

0 comments on commit 77347d2

Please sign in to comment.