POST
|
@Cristian_Galindo `How can I create the ags file using python in ArcGIS Pro?` https://community.esri.com/t5/arcgis-pro-questions/how-to-create-an-arcgis-server-connection-file-with-the-python-3/m-p/1047831/highlight/true#M39792
... View more
04-16-2021
06:32 AM
|
1
|
0
|
1283
|
POST
|
agreed. this has been a major bummer for automation. the following works: # in the same conda environment where i normally import arcpy:
import arcgisscripting
arcgisscripting._createGISServerConnectionFile("ADMINISTER_GIS_SERVICES", "C:/admin", "new.ags", "https://maxscoolserver.org/raster", "ARCGIS_SERVER", True, "C:/admin", "sitemanager", "password123") warning: this is a private method so may not be a great idea, but i'm going to do it until something better comes along.
... View more
04-15-2021
01:39 PM
|
6
|
4
|
7576
|
IDEA
|
haha. yeah, that is kind of overkill. alternatively you can have an empty template mxd file that you use and an empty aprx file and just: templateMxd = "C:/admin/temp_mxd.mxd"
aprx = arcpy.mp.ArcGISProject("C:/admin/temp_aprx.aprx")
map_list = ["map1", "map2", "map3"]
for m in map_list:
existing_maps = aprx.listMaps()
aprx.importDocument(templateMxd)
existing_maps_now = aprx.listMaps()
# not going to assume these maps are being added at any one index position
for ma in existing_maps_now:
if ma not in existing_maps:
# set the name of the imported map
ma.name = m
# done adding new maps to aprx, save it
aprx.saveACopy("C:\admin\aprx_with_new_maps.aprx")
... View more
04-15-2021
07:23 AM
|
0
|
0
|
9425
|
POST
|
That was a very well written question and i thought it had put me on the track to finding the answer i'm looking for as well, but alas, i had to work around it. meanwhile, here are my thoughts on the matter: It seems to me that given the additional data section you mention here we could use python requests to give the server the data parameter, but that doesn't explain why the arcpy sharing of the service is stripping out this inherent functionality (configure popups) of arcgis pro. I have inspected the service definition file that is generated in the arcpy publication process and it has the popupinfo section but it is ignored at the upload service definition stage. unfortunately i was unable publish the service with the popups reflected in the service as i wanted. it seems to be a function of the hosted feature layer. i can't seem to add a data element to an existing feature service. but a hosted feature layer does have this property. well, i should say, the property is not empty in the case of the hosted feature layer. the problem with that, as i understand it, is that if you are working with live data, the hosted feature layer resides in the internal portal database and therefore would need to be recreated every time the data updates in the real backend. I may have missed something obvious here and am eagerly awaiting someone to point it out to me. for me the workaround is injecting the popup info in the client application. this is not ideal because anywhere else you consume this service the popups will also have to be manually configured i.e. anywhere else in the ArcGIS Enterprise. import * as somelayer_popup_template from '../../../content/popupTemplates/somelayer.json';
//more stuff
if (featLayer.title.toLowerCase() === "some layer title") {
featLayer.popupTemplate = PopupTemplate.fromJSON(somelayer_popup_template.popupInfo);
} where somelayer.json is like: {"popupInfo": {
"title": "Some Value: {some_fieldname}",
"fieldInfos": [{
"fieldName": "some_field",
"visible": false,
"isEditable": false,
"format": {
"places": 0,
"digitSeparator": true
},
...],
"description": "<div>some html here</div>"
}
} maybe someone knows of a way to post a new data element to an existing portal item?
... View more
02-24-2021
10:37 AM
|
0
|
6
|
2614
|
POST
|
Good afternoon Brandon, i was wondering if you would mind expanding on your answer here. what do you mean by 'publishing to portal' versus 'publishing to server'? i am running into a similar problem and i thought it was merely a matter of publishing the service, but it isn't working for me. sd = xmap.getWebLayerSharingDraft("FEDERATED_SERVER", "MAP_IMAGE", "TESTING POPUPS") (thinking the above was where you were publishing to server, i also tried sd = xmap.getWebLayerSharingDraft("HOSTING_SERVER", "FEATURE", "TESTING POPUPS") ) then sd.exportToSDDraft("C:/admin/popupdraft.sddraft") then arcpy.StageService_server(in_service_definition_draft=r"C:\admin\popupdraft.sddraft", out_service_definition=r"C:\admin\popupdraft.sd") and finally arcpy.UploadServiceDefinition_server(in_sd_file=r"C:\admin\popupdraft.sd", in_server="https://<hostname>/server", in_folder_type="EXISTING", in_folder="Test") in none of my attempts so far have i been able to see the popupInfos represented in the default webmap of portal. thank you for your time.
... View more
02-22-2021
10:45 AM
|
0
|
0
|
3840
|
BLOG
|
the same message is returned from the python api for arcgis. from arcgis.gis import GIS
gis = GIS(portal_url, "siteadmin", secret)
gis.admin.history(start_date=datetime.datetime.today())
>> 'C:\\Users\\<user>\\AppData\\Local\\Temp\\history.csv' contents of history.csv: {"error":{"code":500, messageCode:"DB_0279", message:"Unable to retrieve history.", details:["Unable to retrieve history."]}}
... View more
11-25-2020
08:41 AM
|
0
|
0
|
2521
|
POST
|
secured services require some kind of authentication. i was first trying to use the arcpy.ImportCredentials method, but arcpy (pro version) no longer allows you to automatically create an arcgis server connection file and since i wanted to automate this i looked for another way. the other option is a token. the web map as json contains 4 root keys: "mapOptions", "operationalLayers", "exportOptions", and "layoutOptions". "operationalLayers" is a list of json objects. if you iterate over those layers and look for your own hostname (or you have other requirements) in the "url" key, you can append a portal token key to the json to authenticate for each required layer. see the mock up example below from my ExportWebMap python geoprocessing script for details. import json
import boto3
import requests
def get_portal_token(portal_host, saj):
"""
this gets a token for authentication into portal for arcgis
"""
url = "https://{}/portal/sharing/rest/generateToken/".format(portal_host)
params = {'f': 'pjson', 'username': saj["username"], 'password': saj["password"], 'referer': "https://{}/portal".format(portal_host)}
token_json = requests.post(url, params)
token = token_json.json()["token"]
return token
#...
portal_host = "someboringschooldomain.edu"
WebMap_as_JSON = arcpy.GetParameterAsText(0)
#get username password:
secret = get_secret(siteadmin_secret, aws_region)
token = get_portal_token(portal_host, secret)
wmaj = json.loads(WebMap_as_JSON)
for layer in wmaj["operationalLayers"]:
if portal_host in layer["url"]:
layer.update({"token": token})
result = arcpy.mp.ConvertWebMapToArcGISProject(json.dumps(wmaj), layoutTemplate)
#...
... View more
11-17-2020
07:06 PM
|
0
|
0
|
2352
|
POST
|
You could also look at the schema.ini file (hidden in windows) that is alongside the csv file you are dealing with. this file allows the configuration of the column data type. For instance, i kept getting an error "Invalid Field Type" when calling arcpy.management.XYTableToPoint the schema.ini file had listed the data type as a string for both columns. line indicated by -1 shows the original results (when Col1=Longitude Text) line indicated by -2 shows the results after updating the Latitude and Longitude columns. note: double quotes are only used to escape otherwise used column delimiters. i.e. if you have a comma in the column value, you will need to "double quote" it so that it doesn't create an additional column for that row.
... View more
08-13-2020
04:43 AM
|
1
|
0
|
1302
|
POST
|
like this bottom_left_X = "-141.108"
bottom_left_Y = "22.055"
top_right_X = "-56.821"
top_right_Y = "52.476"
update_parameters = {'extent': "{}, {}, {}, {}".format(bottom_left_X, bottom_left_Y, top_right_X, top_right_Y)}
... View more
02-27-2020
07:09 PM
|
0
|
0
|
2649
|
POST
|
you can 'get' the spatial reference from a map in the project like this: aprx = arcpy.mp.ArcGISProject("c:\esri\project.aprx")
maps = aprx.listMaps()
map = maps[0]
print(dir(map))
#...
print(dir(map.getDefinition("V2").spatialReference))
and, while you cannot 'set' the spatial reference using 'arcpy', you can with a few additional libraries: import arcpy
import xml.etree.ElementTree as ET
import tempfile
import os
import shutil
from zipfile import ZipFile
print("setting spatial reference")
output_project = "MASTER"
out_dir = os.path.dirname(__file__)
new_aprx_path = os.path.join(out_dir, output_project + "_Project", output_project) + ".aprx"
tempDirMod = tempfile.mkdtemp()
print("tempDirMod:")
print(tempDirMod)
with ZipFile(new_aprx_path, 'r') as zipObj:
# Extract all the contents of aprx (zip file) in temporary directory
zipObj.extractall(tempDirMod)
aprx = arcpy.mp.ArcGISProject(new_aprx_path)
maps = aprx.listMaps()
for m in maps:
extracted_map_CIM_path = m.getDefinition("V2").uRI #i.e. 'CIMPATH=map11/map11.xml' --> "C:\admin\create_query_layers\MASTER_Project\MASTER\map11\map11.xml"
xml_path = extracted_map_CIM_path.split("=")[1]
this_map_xml = os.path.join(tempDirMod, xml_path)
tree = ET.parse(this_map_xml)
root = tree.getroot()
DefaultExtent = root.find("DefaultExtent")
Xmin = ET.SubElement(DefaultExtent, "XMin")
Xmin.text = "-180"
Ymin = ET.SubElement(DefaultExtent, "YMin")
Ymin.text = "-90"
Xmax = ET.SubElement(DefaultExtent, "XMax")
Xmax.text = "180"
Ymax = ET.SubElement(DefaultExtent, "YMax")
Ymax.text = "90"
SpatialReference = ET.SubElement(DefaultExtent, "SpatialReference")
SpatialReference.set("xsi:type", "typens:GeographicCoordinateSystem")
WKT = ET.SubElement(SpatialReference, "WKT")
WKT.text = r"GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433],AUTHORITY["EPSG",4326]]"
XOrigin = ET.SubElement(SpatialReference, "XOrigin")
XOrigin.text = "-400"
YOrigin = ET.SubElement(SpatialReference, "YOrigin")
YOrigin.text = "-400"
XYScale = ET.SubElement(SpatialReference, "XYScale")
XYScale.text = "999999999.99999988"
ZOrigin = ET.SubElement(SpatialReference, "ZOrigin")
ZOrigin.text = "-100000"
ZScale = ET.SubElement(SpatialReference, "ZScale")
ZScale.text = "10000"
MOrigin = ET.SubElement(SpatialReference, "MOrigin")
MOrigin.text = "-100000"
MScale = ET.SubElement(SpatialReference, "MScale")
MScale.text = "10000"
XYTolerance = ET.SubElement(SpatialReference, "XYTolerance")
XYTolerance.text = "8.983152841195215e-09"
ZTolerance = ET.SubElement(SpatialReference, "ZTolerance")
ZTolerance.text = "0.001"
MTolerance = ET.SubElement(SpatialReference, "MTolerance")
MTolerance.text = "0.001"
HighPrecision = ET.SubElement(SpatialReference, "HighPrecision")
HighPrecision.text = "true"
LeftLongitude = ET.SubElement(SpatialReference, "LeftLongitude")
LeftLongitude.text = "-180"
WKID = ET.SubElement(SpatialReference, "WKID")
WKID.text = "4326"
LatestWKID = ET.SubElement(SpatialReference, "LatestWKID")
LatestWKID.text = "4326"
#IMPORTANT NOTE: if you have no spatial reference in your map yet you will want to append a new Element to the xml (as below). Otherwise do as above with DefaultExtent where you would find the SpatialRefrence Node and overwrite existing data.
SpatialReference2 =ET.Element("SpatialReference")
SpatialReference2.set("xsi:type", "typens:GeographicCoordinateSystem")
WKT = ET.SubElement(SpatialReference2, "WKT")
WKT.text = r"GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433],AUTHORITY["EPSG",4326]]"
XOrigin = ET.SubElement(SpatialReference2, "XOrigin")
XOrigin.text = "-400"
YOrigin = ET.SubElement(SpatialReference2, "YOrigin")
YOrigin.text = "-400"
XYScale = ET.SubElement(SpatialReference2, "XYScale")
XYScale.text = "999999999.99999988"
ZOrigin = ET.SubElement(SpatialReference2, "ZOrigin")
ZOrigin.text = "-100000"
ZScale = ET.SubElement(SpatialReference2, "ZScale")
ZScale.text = "10000"
MOrigin = ET.SubElement(SpatialReference2, "MOrigin")
MOrigin.text = "-100000"
MScale = ET.SubElement(SpatialReference2, "MScale")
MScale.text = "10000"
XYTolerance = ET.SubElement(SpatialReference2, "XYTolerance")
XYTolerance.text = "8.983152841195215e-09"
ZTolerance = ET.SubElement(SpatialReference2, "ZTolerance")
ZTolerance.text = "0.001"
MTolerance = ET.SubElement(SpatialReference2, "MTolerance")
MTolerance.text = "0.001"
HighPrecision = ET.SubElement(SpatialReference2, "HighPrecision")
HighPrecision.text = "true"
LeftLongitude = ET.SubElement(SpatialReference2, "LeftLongitude")
LeftLongitude.text = "-180"
WKID = ET.SubElement(SpatialReference2, "WKID")
WKID.text = "4326"
LatestWKID = ET.SubElement(SpatialReference2, "LatestWKID")
LatestWKID.text = "4326"
root.append(SpatialReference2)
#convert xml byte string to string
new_xml = str(ET.tostring(root), 'utf-8')
#write xml over top old file
with open(this_map_xml, "w") as xmlW:
#xml 'wrangler' replaces stubborn escaping and quotation types
xmlW.write(new_xml.replace("&", "&").replace('"',"'"))
##Delete reference to aprx
del aprx
#rezip everything.
shutil.make_archive(os.path.join(out_dir, output_project + "_Project", output_project), "zip", tempDirMod)
new_aprx_path_with_sr = os.path.join(out_dir, output_project + "_Project", output_project + "_withSR") + ".aprx"
# rename the .zip file to .aprx
os.rename(os.path.join(out_dir, output_project + "_Project", output_project + ".zip"), new_aprx_path_with_sr)
#end set spatial ref
* i pulled this from a larger project i'm working on and it hasn't been tested in the above state and may need tweeks.
... View more
02-09-2020
07:45 PM
|
0
|
0
|
1364
|
IDEA
|
it's not much to look it but: #!/usr/bin/env python3
"""
make aprx file, 'add' some maps to it:
#comtypes:
#one of the following installed libraries are required:
#C:\Program Files (x86)\ArcGIS\Desktop10.7\com
#or
#C:\Program Files\ArcGIS\Server\com
"""
import arcpy
import tempfile
import os
import shutil
from shutil import make_archive
out_dir = os.environ["USERPROFILE"] + os.sep + "Desktop"
aprx_name_maps_in_pro = "aprx_with_maps"
## new empty map names:
map_list = ["map1", "map2", "map3"]
#from an empty project (may be able to minimize these items even futher
# but this does what i need.
cimdoc = """<CIMDocumentInfo xsi:type='typens:CIMDocumentInfo' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:typens='http://www.esri.com/schemas/ArcGIS/2.4.0'>
<Version>2.4.0</Version><Build>19948</Build><DocumentTitle>New</DocumentTitle><SavePreview>false</SavePreview>
<UseRelativePath>true</UseRelativePath><Antialiasing>esriBGLAntialiasingNone</Antialiasing>
<TextAntialiasing>esriBGLTextAAliasForce</TextAntialiasing></CIMDocumentInfo>"""
#from an empty project
gisproj = """<CIMGISProject xsi:type="typens:CIMGISProject" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:typens="http://www.esri.com/schemas/ArcGIS/2.4.0"></CIMGISProject>"""
#from an empty project rb in python 3.
EMPTY_PROJECT_BYTES = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
def installComTypes():
"""
install comtypes in virtaul env at runtime, why not.
"""
install_com_types_string = """import subprocess
import sys
def install(package):
subprocess.call([sys.executable, "-m", "pip", "install", package])
install('comtypes')
"""
insall_scrpit_name = "install_comtypes"
install_file = insall_scrpit_name + ".py"
if os.path.exists(install_file):
os.remove(install_file)
with open(install_file, "w") as w_install:
w_install.write(install_com_types_string)
import install_comtypes
#or not
#hack number 1
installComTypes()
import comtypes
def CreateMXD(path):
GetModule('esriCarto.olb')
import comtypes.gen.esriCarto as esriCarto
#print("dir esriCarto:")
#print(dir(esriCarto))
pMapDocument = CreateObject(esriCarto.MapDocument, esriCarto.IMapDocument)
pMapDocument.New(path)
#print("dir pMapDocument:")
#print(dir(pMapDocument))
#print("dir pMapDocument.map:")
#print(dir(pMapDocument.Map))
pMapDocument.Save() #probably not required...
def GetLibPath():
""" Get the ArcObjects library path
It would be nice to just load the module directly instead of needing the path,
they are registered after all... But I just don't know enough about COM to do this
"""
thisCompath=os.path.join(arcpy.GetInstallInfo()['InstallDir'],'com')
desktopCompath = r"C:\Program Files (x86)\ArcGIS\Desktop10.7\com"
serverCompath = r"C:\Program Files\ArcGIS\Server\com"
if os.path.exists(thisCompath):
return thisCompath
elif os.path.exists(desktopCompath):
return desktopCompath
elif os.path.exists(serverCompath):
return serverCompath
else:
raise Exception("#must use desktop or server com libriary (or copy the com folder to a known location")
def GetModule(sModuleName):
""" Generate (if not already done) wrappers for COM modules
"""
from comtypes.client import GetModule
sLibPath = GetLibPath()
GetModule(os.path.join(sLibPath,sModuleName))
def CreateObject(COMClass, COMInterface):
""" Creates a new comtypes POINTER object where
COMClass is the class to be instantiated,
COMInterface is the interface to be assigned
"""
ptr = comtypes.client.CreateObject(COMClass, interface=COMInterface)
return ptr
def create_binary_file(_bytes, file_path):
"""
Create an 'empty' project file
"""
with open(file_path, 'wb') as fh:
fh.write(_bytes)
def create_xml_file(xml_string, file_path):
"""
create an xml file with string of input
"""
with open(file_path, "w") as xml:
xml.write(xml_string)
#temporary workspace (emptied at end)
tempDir = tempfile.mkdtemp()
#write xml to documentinfo.xml
create_xml_file(cimdoc, os.path.join(tempDir, "DocumentInfo.xml"))
#write xml to gisproject.xml
create_xml_file(gisproj, os.path.join(tempDir, "GISProject.xml"))
#hack number 2 write binary data to 007Index.ind
create_binary_file(EMPTY_PROJECT_BYTES, os.path.join(tempDir, "007Index.ind"))
#template pro map name
empty_pro_map = "aprx_empty"
#list of required files for creating aprx file
files = ["007Index.ind","GISProject.xml", "DocumentInfo.xml"]
#zip the files one at a time
for f in files:
shutil.make_archive(os.path.join(out_dir, empty_pro_map), "zip", tempDir)
#empty ArcGISProject
new_aprx_path = os.path.join(out_dir, empty_pro_map) + ".aprx"
#rename the .zip file to .aprx
os.rename(os.path.join(out_dir, empty_pro_map + ".zip"), new_aprx_path)
# everything below here requires python 3 arcpy
# you could split this code here.
# load aprx
aprx = arcpy.mp.ArcGISProject(new_aprx_path)
for m in map_list:
map_path = os.path.join(tempDir, m + ".mxd")
if os.path.exists(map_path):os.unlink(map_path)
#hack number 3
CreateMXD(map_path)
existing_maps = aprx.listMaps()
aprx.importDocument(map_path)
existing_maps_now = aprx.listMaps()
for ma in existing_maps_now:
if ma not in existing_maps:
ma.name = m
#output
aprx.saveACopy(os.path.join(out_dir, aprx_name_maps_in_pro + ".aprx"))
#clear temp files (comment the next line out if you want to review the temp files)
shutil.rmtree(tempDir)
print(tempDir)
save as: <%path%>\add_maps_to_new_aprx.py run it like: C:\Program Files\ArcGIS\Pro\bin\Python\Scripts>propy.bat <%path%>add_maps_to_new_aprx.py the associated toolboxes and geodatabases are created on initial launch, but you could set those if you want.
... View more
02-06-2020
11:34 AM
|
0
|
0
|
10130
|
POST
|
If the script tool in question is also a python script you can view its source by looking at the properties context menu of the script tool in arccatalog. If that is the case, you can explicitly import the script file to your python script by saving a copy of the script in either your python path directory or just right next to (that is, in the same folder) the script you are importing it to like: import arcpy
import customPyScript if the name of the script file you are looking for is customPyScript.py after you import your script you should be able to access its methods by calling it thusly: customPyScipt.method(input, output) If you are importing a binary tool from an existing toolbox you should be able to do: arcpy.ImportToolbox(tbxPath, scriptName) I might have misunderstood your question. What do you mean by "open [your] script in the toolbox"?
... View more
12-06-2013
06:02 PM
|
0
|
0
|
507
|
POST
|
I just imported a script that I want to use in my model however when I import the script into modelbuilder I keep getting the message "This tool has no parameters." In order to expose the parameters of a script to model builder you will need to define the parameters of the script. If you are using a python script tool you will need to right click the script (in arccatalog) and select the properties context menu item. Then you can go to the parameters tab where you will have to define the parameter names and types in order for them to be recognizable by the arcgis environment. In the script, there also must be parameters that are ready to be exposed in the arcgis environment. that is, you will need to ensure that there are input and output parameters (if required) that are defined similar to input = arcpy.GetParameterAsString(0)
output = arcpy.SetParameter(1) Note that you will need to have a parameter that corresponds to these script parameters defined the scripts properties page for parameters in order for it to function correctly. If you are using a custom geoprocessing tool written in arcobjects you may have to register externally created libraries using the EsriRegAsm.exe http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//0001000004n6000000 and ensure any configurations and prerequisites are available to the application. If you provide more detail about your script or the script itself I may be able to offer more insight. Hope this helps
... View more
12-06-2013
11:19 AM
|
0
|
0
|
1384
|
Title | Kudos | Posted |
---|---|---|
1 | 08-13-2020 04:43 AM | |
1 | 04-15-2021 02:52 PM | |
1 | 04-16-2021 06:32 AM | |
6 | 04-15-2021 01:39 PM | |
1 | 07-24-2019 07:44 PM |
Online Status |
Offline
|
Date Last Visited |
04-16-2021
10:29 AM
|