POST
|
This is an interesting thought! I had stumbled across this StackOverflow answer regarding why arcpy.da cursors are so much faster: https://gis.stackexchange.com/a/108809/19883 If you pop open the slides the dev links to, it does appear that arcpy.da geometry queries are relatively slow compared to the rest of the data access lib's performance. I would have assumed that the shape doesn't need to be parsed if you're not accessing it, but the perf difference between feature layers and tables definitely indicates otherwise. I tried with the regular cursor, and it does seem to be a bit faster iterating through my dataset. However, given that I'm operating on a relatively small portion of the overall table, I think the `where_clause` on a data access cursor will be the wisest choice. Thanks for the thoughts.
... View more
07-22-2022
07:06 AM
|
0
|
0
|
1890
|
POST
|
Thanks for the tips! On 1), I do need the edit session due to the Relationship Class. ArcPy raises an Exception otherwise. On 2), agreed, it's redundant. It's an artifact from my original approach, where I was trying to used the UpdateCursor to loop through _all_records. I doubt the Python List lookup was the issue, though. And on 3), I wish I could get away with the GUI. The actually migration will require some additional computations to re-summarize some affected records.
... View more
07-22-2022
07:01 AM
|
0
|
1
|
1890
|
POST
|
I believe this was a case of a corrupted file geodatabase. While debugging, I usually try to copy/paste the layers into a new file geodatabase, which has helped deal with corruption in the past. That did not work here. I went back to the FGDB source and got a fresh copy of the data, and performance returned to normal.
... View more
07-20-2022
03:24 PM
|
0
|
0
|
1938
|
POST
|
I'm attempting to update a numeric field using an arcpy.da.UpdateCursor. I'm applying the update to a Feature Layer and Table, which participate in a One to Many Relationship. The Feature layer is quite large, with 1,219,495 Polygon records. The table has even more records at 4,735,679 rows. The update should only be applied if certain conditions are met. If the Child Table's Provider field has a value of "Optimum", it needs updated. If the Parent Feature's MaxDownload field is 1,000, it needs updated. I'm doing the queries first via SearchCursor, and saving the relevant IDs that satisfy the query. Then, in an edit session, I'm attempting to update the relevant fields using a where_clause to select the OIDs I need. import datetime as dt
import arcpy
def log_it(msg):
print(f"[{dt.datetime.now()}]: {msg}")
return
def query_str_in_list(field_name, values):
vals = "'" + "', '".join(values) + "'"
return f"{field_name} IN ({vals})"
def query_int_in_list(field_name, values):
vals = ", ".join([str(v) for v in values])
return f"{field_name} IN ({vals})"
def main():
start_time = dt.datetime.now()
print(f"Starting script at {start_time}")
arcpy.env.workspace = r"C:\dev\arcgis\NYS-DPS\NysDpsBroadbandMap\2022-06-01_Analysis\2022-06-01_Analysis\NysDpsBroadbandMap.gdb"
global_ids = []
provider_oids = []
with arcpy.da.SearchCursor(
"StandardProviders",
["ParentGlobalID", "OBJECTID"],
where_clause="Provider = 'Optimum'",
) as search_cursor:
for row in search_cursor:
global_ids.append(row[0])
provider_oids.append(row[1])
polygon_oids = [
row[0]
for row in arcpy.da.SearchCursor(
"StandardSummaryPolygons",
["OBJECTID"],
where_clause=query_str_in_list("GlobalID", global_ids)
+ " AND MaxDownload = 1000",
)
]
log_it(
f"Beginning to edit {len(provider_oids)} Provider Records and {len(polygon_oids)} Polygon Records"
)
with arcpy.da.Editor(arcpy.env.workspace) as edit_session:
with arcpy.da.UpdateCursor(
"StandardSummaryPolygons",
["OID@", "MaxDownload"],
where_clause=query_int_in_list("OBJECTID", polygon_oids),
) as polygon_update_cursor:
for idx, row in enumerate(polygon_update_cursor):
log_it(f"{idx} Polygon Iterations")
oid = row[0]
if oid in polygon_oids:
polygon_update_cursor.updateRow([oid, 940])
with arcpy.da.UpdateCursor(
"StandardProviders",
["OID@", "Download"],
where_clause=query_int_in_list("OBJECTID", provider_oids),
) as provider_update_cursor:
for idx, row in enumerate(provider_update_cursor):
log_it(f"{idx} Provider Iterations")
oid = row[0]
if oid in provider_oids:
provider_update_cursor.updateRow([oid, 940])
end_time = dt.datetime.now()
duration = end_time - start_time
print(f"Finished at {end_time} after executing for {duration}")
return
if __name__ == "__main__":
main() The script is going quite slow, and it appears that the Polygon Feature Class is the root cause. When iterating through the cursor, each iteration is taking 2 seconds. Iterating through the table gives the performance I would expect. Here's a log snippet: ## Parent Table Log (Polygon Features)
Starting script at 2022-07-20 14:13:51.937132
[2022-07-20 14:13:59.535107]: Beginning to edit 276149 Provider Records and 212815 Polygon Records
[2022-07-20 14:13:59.801700]: 0 Polygon Iterations
[2022-07-20 14:14:01.015486]: 1 Polygon Iterations
[2022-07-20 14:14:02.363565]: 2 Polygon Iterations
[2022-07-20 14:14:03.780736]: 3 Polygon Iterations ## Child Table Log (Table Rows)
[2022-07-20 14:19:10.037031]: 6740 Provider Iterations
[2022-07-20 14:19:10.037031]: 6741 Provider Iterations
[2022-07-20 14:19:10.038029]: 6742 Provider Iterations
[2022-07-20 14:19:10.038029]: 6743 Provider Iterations Am I simply running into physical limits due to the volume of the data? Are there any performance gains that could be implemented here? Thanks!
... View more
07-20-2022
11:41 AM
|
0
|
9
|
1998
|
IDEA
|
I propose that configurable usage alarms be provided for each API key that is created in the Developer's dashboard. Any number of metrics could be very useful, but something as simple as "alert me after 15,000 geocodes this month" would make API key maintenance and management much easier for ArcGIS developers. According to the developers.arcgis.com documentation regarding API Key Security, there are a few best practices for avoiding abuse of our API keys. These practices include limiting public exposure, configuring allowed referrers, scoping your API key to just the required services, rotating your keys, and, perhaps most importantly, monitoring usage. Most of the best practices listed in the documentation are one-time development concerns. For example, I'll set up the referrer headers when I create the API key (or rotate it), then probably never think about it again. Usage monitoring, however, is not a set-it-and-forget-it concern. Effective monitoring would require checking the dashboard quite vigilantly. Depending on a project's budget and the abuse the took place, the abnormal or abusive usage could be quite expensive by the time it is noticed. Further, as the number of apps under any individual developer's maintenance purview begins to grow, the expectation for manual usage monitoring becomes pretty unrealistic. I believe this feature could really help avoiding unexpectedly large bills and/or damage to our systems.
... View more
10-18-2021
08:40 AM
|
8
|
3
|
1093
|
POST
|
I've seen similar behavior, too. I feel like it's more frequent from the WebApp, but would need to experiment a little to say for certain. It sounds like your repeats are "optional" in a lot of cases? If so, you can try using the `minimal` appearance. This will leave the fields absent from the form until the user clicks the plus button. My theory is that having the fields hidden will prevent the `nulls` from getting written to the related table's feature layer. YMMV.
... View more
05-14-2021
06:38 AM
|
0
|
0
|
614
|
POST
|
Hello, I'm trying to integrate an application with Survey123 using the documentation found here: https://doc.arcgis.com/en/survey123/reference/integratewithotherapps.htm In our application, users will be presented a map of features from a system of record (SOR). From there, they may decide they want to update that record with new information gathered from the field. For the field work, we're using ArcGIS Survey123, which has the benefit of isolating the field data in a Feature Service, allowing the field data to be reviewed before loading it into the SOR. The features from the system of record are polygons, many of which have been created by buffering points. Thus, they have too many vertices to be passed to the ArcGIS Survey123 field app in the URL using the `field:fieldName=This%20value` syntax. To get around this, we're using the /applyEdits endpoint of the S123 feature service to POST a new record with the data from the SOR from our JavaScript application. Once the new record is created, we would like to use the globalid (or ObjectId) to open the field application to the newly created feature. This workflow seems to work well with the Survey123 Web App. Using the `?mode=edit&globalId=uuid` style query, the app opens up to the new feature. However, when I try to carry this same logic over to the Field App (which is what our requirements call for), the app keeps opening to an empty form. I've created a super-simple survey and shared it publicly to exemplify the issue in this CodePen: https://codepen.io/vitale232-the-vuer/project/editor/DNeRYO?open_file=index.html FWIW, the S123 form we're trying to get to production has many repeats. However, we're not trying to carry over any of the repeat fields from the SOR. Does anyone know what's going wrong here? Why can't I open a feature that would be in the inbox without using the inbox? The documentation seems to imply that this is a viable solution. Thanks for reading!
... View more
05-14-2021
05:33 AM
|
1
|
1
|
702
|
POST
|
Hi Rene, Thanks for the quick reply! I did not know about the rel="preload" property. I'll def keep that in mind. I do believe that I am calling loadModules on the initialization of my component, which is when the geometryEngine*.js scripts are added. However it appears that the worker threads don't get hydrated with the geometryEngineWorker.js scripts until the union method is invoked. Check out the waterfall here: With fresh eyes, it seems like calling the method on an empty array after the geometryEngineAsync has loaded is giving me the desired result... The threads are loaded and ready to rip by the time the user would get around to interacting with the map. Is there any reason not to do this? // Angular 11 service
@Injectable({
providedIn: 'root'
})
export class UnionModulesService {
public geometryEngineAsync: __esri.geometryEngineAsync;
public Graphic: __esri.GraphicConstructor;
constructor() {}
public async loadModules(
esriStore: EsriStore
) : Promise<[__esri.geometryEngineAsync, __esri.GraphicConstructor]> {
try {
if (this.geometryEngineAsync && this.Graphic) {
return [this.geometryEngineAsync, this.Graphic];
} else {
const [geometryEngineAsync, Graphic] = await esriStore.require<
[__esri.geometryEngineAsync, __esri.GraphicConstructor]
>(['esri/geometry/geometryEngineAsync', 'esri/Graphic']);
this.geometryEngineAsync = geometryEngineAsync;
this.Graphic = Graphic;
// Call the union method on an empty array to get everything ready?
this.geometryEngineAsync
.union([])
.then((x) => console.log('warmed it up', x));
return [geometryEngineAsync, Graphic];
}
} catch (error) {
console.error('UnionModulesService.loadModules', error);
throw error;
}
}
}
... View more
02-12-2021
05:19 AM
|
0
|
0
|
762
|
POST
|
I've been really enjoying `geometryEngineAsync` in my JS apps. I'm loading v 4.18 into an Angular 11 app with `esri-loader`. The first time I invoke the `union` method on an array of Polygons, there are numerous scripts downloaded. My questions is this: Is there a way to preload these scripts prior to calling the fuction? The first time I render the Sketch Widget graphics, there's a bit of lag. After that it's buttery smooth. Thanks!
... View more
02-11-2021
03:06 PM
|
0
|
2
|
814
|
POST
|
Hello, It looks like the `viewModel.measurement` property gets set to `null` by the widget when you first click the "New measurement" button. Since you're watching the property for ALL changes, the null gets passed into your event handler. You can simply check if the property is "truthy" before trying to access the properties by guarding your code in an if statement. This is a common pattern, and it's useful outside of the JS API. Here's a working sample: <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>Esri Playground</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.18/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.18/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require([
"esri/views/MapView",
"esri/WebMap",
"esri/widgets/DistanceMeasurement2D",
"esri/widgets/AreaMeasurement2D",
"esri/widgets/AreaMeasurement2D/AreaMeasurement2DViewModel",
], function (
MapView,
WebMap,
DistanceMeasurement2D,
AreaMeasurement2D,
AreaMeasurement2DViewModel
) {
// load a webmap
const webmap = new WebMap({
portalItem: {
id: "990d0191f2574db495c4304a01c3e65b",
},
});
// create the map view
const view = new MapView({
container: "viewDiv",
map: webmap,
});
var measurementWidget = new AreaMeasurement2D({
view: view,
});
view.ui.add(measurementWidget, "top-right");
measurementWidget.watch(
"viewModel.measurement",
function (measurement) {
console.log({ measurement });
if (measurement) {
console.log("Area: ", measurement.area);
}
}
);
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
... View more
01-17-2021
12:23 PM
|
0
|
1
|
715
|
POST
|
Stephen, Thanks so much for chiming in! This does, in fact, seem to be the solution I was looking for. So simple! It's working in the example provided here, as well as in a sample Angular app. I think you're on to something with this line of thinking: Stephen Runk wrote: In this case maybe the view is not finished initializing and that is triggering the basemapGallery to initialize a second time or at least cancel its initial requests?
... View more
05-26-2020
01:57 PM
|
0
|
0
|
1215
|
POST
|
Hey all, I've been trying to chase down an issue where the Basemap Gallery Widget in the 4.15 JS API is aborting requests, which results in an incomplete list of basemaps. The application we're developing is accessing data via our own Portal deployment, which is where the JS API should be searching for basemaps. Upon first load, often times the basemap gallery list will load successfully. However, refreshing the page will almost certainly create the issue using the example here. This is what it looks like when the basemap requests get aborted: Here's an example error: [esri.Basemap] #load() Failed to load basemap (title: 'Basemap', id: '1725208f67e-basemap-8')
{name: "AbortError", message: "Aborted", details: undefined, dojoType: "cancel"} Our application will be using WebMaps from the JS API instead of Maps. The issue seems to be worse when visualizing a WebMap rather than a Map. Further, the application we're developing is an Angular 8 app, and the issue seems to be worse when a new map is brought into the page from behind an `*ngIf` directive. If I understand ngIf correctly, this Angular directive totally removes the map <div> element from the page when the "if" condition is false. So, said another way, the issue may be worse when the map is dynamically added and/or removed from the page. I'm able to replicate this on Windows and Ubuntu in Chrome and Firefox. Also of note, I am not the Portal administrator, thus I'm unaware of how it was originally configured. I could likely get in touch with the admin if there's evidence pointing to a config issue. Here's a simple example that references our Portal instance and a public WebMap from the Portal. Just open up devtools, load the page, and chances are you'll see many of the basemaps' requests were aborted. If not, refresh the page and the issue should appear. <html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<!--
ArcGIS API for JavaScript, https://js.arcgis.com
For more information about the basemaps-portal sample, read the original sample description at developers.arcgis.com.
https://developers.arcgis.com/javascript/latest/sample-code/basemaps-portal/index.html
-->
<title>Portal Basemap Abort Errors</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.15/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.15/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require([
"esri/config",
"esri/WebMap",
"esri/portal/Portal",
"esri/views/MapView",
"esri/widgets/BasemapGallery",
"esri/widgets/Search",
"esri/widgets/Expand",
], function(
esriConfig,
WebMap,
Portal,
MapView,
BasemapGallery,
Search,
Expand,
) {
esriConfig.portalUrl = "https://gistestportal.vhb.com/site";
const portal = new Portal();
portal
.load()
.then(function() {
const zoomLevel = 11;
const map = new WebMap({
portalItem: {
id: 'ae1cb74010f34c16bf2c61941555ed23',
}
});
const view = new MapView({
container: "viewDiv",
map: map,
center: [-79.9959, 40.4406],
zoom: zoomLevel,
});
const basemapGallery = new BasemapGallery({
view: view
});
const bgExpand = new Expand({
view: view,
content: basemapGallery
});
view.ui.add(bgExpand, "top-right");
})
.catch(function(error) {
console.error(error);
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Any advice would be greatly appreciated! Thanks for your help.
... View more
05-26-2020
10:34 AM
|
0
|
2
|
1300
|
POST
|
No worries, sorry I missed the mark. If you come up with a solution, please share it here. I'm also interested.
... View more
05-19-2020
05:38 AM
|
0
|
0
|
690
|
POST
|
Are you trying to add features into an existing Feature Class on Portal/AGOL, or create a brand new item with the shapefile? If the latter, I'm not sure if you can do it or not. If the former, I' had good luck with this sample from Esri: Create a FeatureLayer from a shapefile | ArcGIS API for JavaScript 4.15 The sample will show you how to get the file attached to a form's input field, submit the file to AGOL (or portal) using the /features/generate endpoint to transform the shapefile to a JS API compatible object, then transform it to a feature layer. From there, you'll have the data in the JS API and can add/update/delete whatever needs it. Hope that helps.
... View more
05-19-2020
03:14 AM
|
0
|
2
|
690
|
Title | Kudos | Posted |
---|---|---|
1 | 05-14-2021 05:33 AM | |
8 | 10-18-2021 08:40 AM |
Online Status |
Offline
|
Date Last Visited |
12-16-2023
06:55 PM
|