|
POST
|
A few years back, ESRI moved away from sending CD/DVDs of the conference proceedings (let's just limit the discussion to the technical workshops for now) because the content was getting posted to the website. Cost savings, environment, blah blah blah. I went searching for the slides from a workshop FROM THIS PAST YEAR'S CONFERENCE and hardly of the slide PDFs are posted. What the hell, ESRI? Either post the stuff or give us back our mailed CD/DVDs. Specifically, I was looking for "ArcGIS Server Performance and Scalability: Optimizing GIS Services." This isn't exactly a niche topic.
... View more
12-17-2015
09:56 AM
|
0
|
8
|
8582
|
|
POST
|
Michael Volz As an FYI, same script I posted but just changed the one line to use the truncate command. Here are the results of a few runs: ================================================== Processing start time: 2015-12-16 13:51:26.462000 ================================================== * Deleting existing records in SDE: 2015-12-16 13:51:28.509000 Time elapsed: 0.00799989700317 seconds * Starting record transfer from DVLive: 2015-12-16 13:51:28.527000 Time Elapsed: 4.20300006866 seconds ================================================== Processing end time: 2015-12-16 13:51:32.741000 ================================================== Number of record(s) in the DIADvisor database: 3218 >>> ================================ RESTART ================================ >>> ================================================== Processing start time: 2015-12-16 13:58:36.772000 ================================================== * Deleting existing records in SDE: 2015-12-16 13:58:38.863000 Time elapsed: 0.0090000629425 seconds * Starting record transfer from DVLive: 2015-12-16 13:58:38.878000 Time Elapsed: 3.69099998474 seconds ================================================== Processing end time: 2015-12-16 13:58:42.640000 ================================================== Number of record(s) in the DIADvisor database: 3222 >>> ================================ RESTART ================================ >>> ================================================== Processing start time: 2015-12-16 14:06:43.055000 ================================================== * Deleting existing records in SDE: 2015-12-16 14:06:45.097000 Time elapsed: 0.0090000629425 seconds * Starting record transfer from DVLive: 2015-12-16 14:06:45.122000 Time Elapsed: 4.10700011253 seconds ================================================== Processing end time: 2015-12-16 14:06:49.243000 ================================================== Number of record(s) in the DIADvisor database: 3228
... View more
12-16-2015
02:08 PM
|
0
|
0
|
6688
|
|
POST
|
Holy smokes- we have a WINNER. Thanks Joshua Bixby I've run it a couple of times and the times dropped from 60-70 seconds down to under a second. That's fabulous. You were right to assume that the table was not versioned. It contains stream gage values for the last 3 days so the contents are always changing with no need for preserving the older data (that's stored in the Access Database that the gage software uses anyways). While we're all talking, is there a "better" way to handle the transfer of records from Access to SDE? The Query Table in Access has the same definition as the SDE table.
... View more
12-16-2015
02:05 PM
|
1
|
0
|
6688
|
|
POST
|
I'm not a Python expert so I'm wondering if my script is already the most efficient way of doing this or if there's a better way. We have a table in SDE (SQLServer2012 back end FWIW) and we're running a Windows Task scheduled service to pull records from an Access Database over to the SDE table every 15 minutes. Because the table is providing content to a web map, I cannot delete the table (at least I don't think I can without affecting the web map). For this reason, I chose to develop a script that empties the table of all records and then inserts the updated records. Usually, we're talking about 2800-3400 records at any given time. Digging through my script, I'm seeing that the initial step of deleting the existing records is taking *much* longer than the task of copying records from the Access database into the SDE world. I'm quite shocked by that; I suspected that the reverse was true. Here is my script: import sys
import os
import linecache
import logging
import arcpy
import time
from datetime import datetime
from arcpy import env
file01 = r"\\pmc-floodwatch\DIADvisorDatabases\DvLive.mok" #This file must exist
file02 = r"\\pmc-floodwatch\DIADvisorDatabases\DvLive.mno" #This file must NOT exist
expression = '1=1' #SQL shorthand which select all records
theTable = "SPW_GIS_PROD.SPW_GDBA.HYDROGRAPHY__tblGageData"
#Establish the error log file
logger = logging.getLogger('errorLog')
hdlr = logging.FileHandler(r'\\python\errorLog.log')
logger.addHandler(hdlr)
# The tables within DIADvisor must not be accessed during its daily database maintenance.
# OneRain recommends checking for the existence and non-existence of two specific files.
# If both conditions are true, it is safe to proceed with connecting to the data within
# the dvLive Access database
if os.path.exists(file01) and not os.path.exists(file02):
print "=================================================="
print "Processing start time: " + str(datetime.now())
print "==================================================" + "\n"
env.workspace = r"C:\Users\spwscc\AppData\Roaming\ESRI\Desktop10.3\ArcCatalog\SPW_GDBA@[email protected]"
try:
# Set some local variables
tempTableView = "gageTableView"
# Execute MakeTableView
arcpy.MakeTableView_management(theTable, tempTableView)
# Execute SelectLayerByAttribute to select all records
arcpy.SelectLayerByAttribute_management(tempTableView, "NEW_SELECTION", expression)
print " * Deleting existing records in SDE: " + str(datetime.now())
timeDelStart = time.time()
# Execute GetCount and if some records have been selected, then execute
# DeleteRows to delete the selected records.
if int(arcpy.GetCount_management(tempTableView).getOutput(0)) > 0:
arcpy.DeleteRows_management(tempTableView)
timeDelEnd = time.time()
timeDelElapsed = timeDelEnd - timeDelStart
print " Time elapsed: " + str(timeDelElapsed) + " seconds" + "\n"
# Now connect to the DIADvisor access database and import the most recent data
# This requires the OLD DB connection previously established using ArcCatalog
counter = 0
print " * Starting record transfer from DVLive: " + str(datetime.now())
timeStartTransfer = time.time()
accessRows = arcpy.SearchCursor(r"C:\Users\spwscc\AppData\Roaming\ESRI\Desktop10.3\ArcCatalog\jetConnectForDvLive.odc\last3days")
curSde = arcpy.InsertCursor(theTable)
# Loop through the results returned via the OLE DB connection
for cRow in accessRows:
curSensorId = cRow.sensor_id
curEpoch = cRow.epoch
curData = cRow.data
curDataValue2 = cRow.dataValue2
counter += 1
#Insert a new row into the SDE table with the current DIADvisor record's information
row = curSde.newRow()
row.SENSOR_ID = curSensorId
row.EPOCH = curEpoch
row.DATA = curData
row.dataValue2 = curDataValue2
curSde.insertRow(row)
timeEndTransfer = time.time()
timeTransferElapsed = timeEndTransfer - timeStartTransfer
print " Time Elapsed: " + str(timeTransferElapsed) + " seconds" + "\n"
# We're done so perform some variable cleanup
del row
del accessRows
del curSde
del cRow
print "=================================================="
print "Processing end time: " + str(datetime.now())
print "==================================================" + "\n"
print "Number of record(s) in the DIADvisor database: " + str(counter) + "\n"
except Exception as e:
# If an error occurred, print line number and error message
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
theMessage = "\n" + 80*"#" + "\n" + 80*"#" + "\n"
theMessage = theMessage + "DATE/TIME: " + str(datetime.now()) + ":" + "\n"
theMessage = theMessage + "EXECPTION: " + str(e) + "\n" + "\n"
theMessage = theMessage + "CALLBACK TRACE: " + "\n"
theMessage = theMessage + 20*" " + "File: " + str(exc_tb.tb_frame.f_code.co_filename) + "\n"
theMessage = theMessage + 20*" " + "Line " + str(exc_tb.tb_lineno) + ": " + str(linecache.getline(exc_tb.tb_frame.f_code.co_filename, exc_tb.tb_lineno))
theMessage = theMessage + 20*" " + "Exception Type: " + str(exc_type)
print theMessage
logger.error(theMessage)
else:
sys.exit() In terms of runtimes, here's a quick sampling: ================================================== Processing start time: 2015-12-16 12:49:01.322000 ================================================== * Deleting existing records in SDE: 2015-12-16 12:49:03.491000 Time elapsed: 66.4879999161 seconds * Starting record transfer from DVLive: 2015-12-16 12:50:10.022000 Time Elapsed: 4.12600016594 seconds ================================================== Processing end time: 2015-12-16 12:50:14.157000 ================================================== Number of record(s) in the DIADvisor database: 3167 >>> ================================ RESTART ================================ >>> ================================================== Processing start time: 2015-12-16 13:00:50.661000 ================================================== * Deleting existing records in SDE: 2015-12-16 13:00:53.012000 Time elapsed: 71.2430000305 seconds * Starting record transfer from DVLive: 2015-12-16 13:02:04.295000 Time Elapsed: 4.01099991798 seconds ================================================== Processing end time: 2015-12-16 13:02:08.314000 ================================================== Number of record(s) in the DIADvisor database: 3173 So- am I already clearing the contents of my SDE table in the most efficient way possible or is there a better way? Thanks! Steve
... View more
12-16-2015
01:08 PM
|
0
|
8
|
11919
|
|
POST
|
Your other option, of course, is to parse the KML file and create a featureLayer on the fly. KML files are just XML anyways so, for simple KMLs of points (and possibly lines), this wouldn't be that difficult (albeit tedious).
... View more
12-15-2015
02:44 PM
|
0
|
2
|
1586
|
|
POST
|
Ok, found a solution. I don't know if this creates issues further down the road but... The Attribute Inspector does have an onShow event but anything inside is ignored. You have to hook into the event that occurs when the attribute inspector receives a feature so I ended up with using the featureLayer onClick event like this: repairLayer.on("click", function(evt) {
if(evt.ctrlKey) {
// Only display the attribute inspector if the user clicks and holds down the Control key. Otherwise,
// just show the standard infoWindow
dojo.stopEvent(evt); //Prevent the infoWindow from displaying
domStyle.set('leftPanel','display','inline');
var qFeature = new Query();
qFeature.objectIds = [Number(evt.graphic.attributes.OBJECTID)];
qFeature.outFields = ["*"];
qFeature.returnGeometry = false;
repairLayer.selectFeatures(qFeature, FeatureLayer.SELECTION_NEW, function(features) {
if(features.length > 0) {
updateFeature = features[0];
if (!dijit.byId('btnPhotoFolder')) {
//Make sure the button doesn't already exist..
var photoPathButton = new Button({label: " ", "iconClass": "openFolderIcon", id: "btnPhotoFolder", showLabel: false},domConstruct.create("div"));
photoPathButton.onClick = function() {document.getElementById('dirPhotoFolder').click();};
var photoPathField = dijit.byId('dijit_form_TextBox_6');
domConstruct.place(photoPathButton.domNode, photoPathField.domNode, "after");
}
}
});
app.map.resize();
app.map.reposition();
}
}); I'm only using the attribute layer with one, specific layer so I can safely assume some consistency with respect to the name of the dijit I want my button to appear next to. If you had multiple layers tied to your attribute inspector, you'd have some more work with respect to finding where to insert your button.
... View more
12-15-2015
02:41 PM
|
0
|
0
|
1407
|
|
POST
|
Check out this previous thread. Here's a rough demo. Not great but maybe you can refine it.
... View more
12-15-2015
12:13 PM
|
2
|
0
|
1917
|
|
POST
|
UPDATE: So the issue is partially one of timing. At page load, the text field dijit I'm referring to simply doesn't exist. Only when the attribute inspector is being shown and has a feature will the dijit exist. I'm now trying to hook into one of the undocumented events (onStart) but it's ignoring the code..
... View more
12-15-2015
11:25 AM
|
0
|
1
|
1407
|
|
POST
|
The subject line is pretty self explanatory. I'm having trouble doing it, though. I'm using this sample as a guideline. I have a text field which represents a file path and I want to insert a button next to the field which then fires off the folder browser from the HTML5 File API. I've placed the attribute inspector inside a hidden div which gets displayed if a user control clicks on a feature in the map. Anyways, my "Cancel" button shows up fine but the code chokes (no error in the console) when it comes to inserting my simple button after the relevant text field: app.attInspector = new AttributeInspector({
layerInfos: layerInfos
}, 'prjDetailEditor');
var cancelButton = new Button({ label: "Cancel", "class": "cancelButton"},domConstruct.create("div"));
domConstruct.place(cancelButton.domNode, app.attInspector.deleteBtn.domNode, "after");
var photoPathButton = new Button({ label: "Photo Path", "class": "openFolderIcon", showLabel: false},domConstruct.create("div"));
var photoPathField = dijit.byId('dijit_form_TextBox_6');
domConstruct.place(photoPathButton.domNode, photoPathField.domNode, "after"); If I set a breakpoint on the last line (domConstruct..), photoPathButton exists but photoPathField is undefined. Is there a method associated with the AttributeInspector such that I can search for and get a reference to my particular text field? Thanks, Steve
... View more
12-15-2015
10:05 AM
|
0
|
2
|
3220
|
|
POST
|
Yeah. I bumped that thread for an update to no avail. It just feels like it's in beta with the glaring deficiencies. Since there is no refresh method, I did create a request on the ArcGIS Ideas website.
... View more
12-09-2015
12:52 PM
|
0
|
5
|
2327
|
|
POST
|
[say that three times fast] So I'm getting frustrated with the FeatureTable dijit since it seems like a half done widget. The layer I am displaying with the featureTable has a date field along with several double fields that represent currency. In Arcmap, I tried set the aliases for all columns and tried applying a format as well. When the mXD was published as a service, the field name aliases appear but the formatting doesn't. As I learned from another thread, ESRI has actually "turned off" the date formatter that you can specify during construction of the widget (nice of you to note this in your documentation, ESRI!) so that leaves me currently.....screwed. What I have tried to do is create formatter functions in my app and then specify them to the appropriate dGrid columns using Set: var dateField = myTable.colums[6];
var drCostField = myTable.columns[9];
dateField.set('formatter',formateDate);
drCostField.set('formatter',formatCurrency); This does....nothing. And, from what I can see, there is not refresh method on the featureTable. Has anyone overcome this?.. Steve
... View more
12-09-2015
11:17 AM
|
0
|
7
|
5166
|
|
POST
|
Rickey Fite no, not any more. I was having issues with all of this so I decided to have two "apps" one for just editing and then a second one which my users would use to view the data. By doing this , I got around the need for using the initEditing function that was part of the sample in my original post. I *think* you can resolve your issue by doing this: map.on("layers-add-result", function(event) { initEditing(event); }); In the above example, the event variable from the layers-add-result event will contain a layers collection.
... View more
12-09-2015
11:07 AM
|
1
|
2
|
2004
|
|
POST
|
ESRI only seems to cut breaks with SMALL governmental orgs or fed departments. Otherwise, you're kinda lumped in with commercial clients. I asked the guy who handles our license negotiating and he said that setting up an enterprise license agreement between ESRI and our county wouldn't be worth it so we just continue to battle, line by line on the license agreements. Anyways, I'm not saying don't look into it but just don't get your hopes too high.
... View more
12-08-2015
10:00 AM
|
0
|
0
|
2926
|