|
POST
|
This seems like a good job for Python. This script assumes velocity in m/s and constant acceleration between the points. It outputs a table that lists each trip with all crossed lines with crossing time and velocity. To run it: open the Python window copy and paste the script below edit the input and output variables (you don't need to change anything below line 16) hit enter import arcpy, datetime
# define inputs
in_points = "Path/to/points"
trip_field = "TripID"
time_field = "Time"
velocity_field = "Velocity"
in_cross_sections = "Path/to/cross_sections"
cross_section_field = "CrossSectionID"
# define outputs
# for your huge amount of data, I recommend saving into RAM, so it runs faster
# don't forget to export the table afterwards!
out_folder = "memory"
out_name = "result"
# function for calculating the time and velocity at which the vehicle hits the point of interest
# this assumes constant acceleration!
# v0: start velocity in [m/s]
# a: acceleration in [m/s/s]
# s: distance from start to point of interest in [m]
# returns a tuple of (seconds, velocity)
def calc_time_and_velocity(v0, a, s):
# for constant acceleration:
# v(t) = a * t + v0
# s(t) = 0.5 * a * t^2 + v0 * t
# ==> t(s) = -v0/a +- sqrt( (v0 / a)^2 + 2 * s / a )
t = -v0 / a - math.sqrt( math.pow(v0 / a, 2) + 2 * s / a)
if t <= 0:
t = -v0 / a + math.sqrt( math.pow(v0 / a, 2) + 2 * s / a)
v = a * t + v0
return (t, v)
# create output table
out_table = arcpy.management.CreateTable(out_folder, out_name)
arcpy.management.AddField(out_table, "Trip", "LONG")
arcpy.management.AddField(out_table, "CrossSection", "LONG")
arcpy.management.AddField(out_table, "Time", "DATE")
arcpy.management.AddField(out_table, "Velocity", "FLOAT")
# read input data
points = [row for row in arcpy.da.SearchCursor(in_points, ["SHAPE@", trip_field, time_field, velocity_field])]
cross_sections = [row for row in arcpy.da.SearchCursor(in_cross_sections, ["SHAPE@", cross_section_field])]
sr = points[0][0].spatialReference
# get all trips
trips = list({p[1] for p in points})
# start writing into the output table
with arcpy.da.InsertCursor(out_table, ["Trip", "CrossSection", "Time", "Velocity"]) as cursor:
# loop through the trips
for trip in trips:
# extract the points of that trip
trip_points = [p for p in points if p[1] == trip]
# sort by time
trip_points.sort(key=lambda p: p[2])
# loop through point pairs
for i in range(1, len(trip_points)):
p1 = trip_points[i-1]
p2 = trip_points[i]
line = arcpy.Polyline(arcpy.Array([p1[0].firstPoint, p2[0].firstPoint]), sr)
# find intersecting cross sections
intersecting_cs = [cs for cs in cross_sections if not line.disjoint(cs[0])]
# loop through those cross_sections
for cs in intersecting_cs:
# get the intersection point
p = line.intersect(cs[0], 1)
# calculate time and velocity
dv = p2[3] - p1[3]
dt = (p2[2] - p1[2]).seconds
a = dv / dt
s = p1[0].distanceTo(p)
t, v = calc_time_and_velocity(p1[3], a, s)
time = p1[2] + datetime.timedelta(seconds=t)
# write into the output table
cursor.insertRow([trip, cs[1], time, v]) Results for some made-up test data: Again, this script assumes velocity values given in meters per second, so you have to calculate that from your values (I'm assuming these are km/h).
... View more
09-28-2022
10:19 AM
|
1
|
5
|
5089
|
|
POST
|
With Arcade: return Average(Split($feature.TextField, "-", -1, true))
... View more
09-28-2022
07:37 AM
|
0
|
0
|
1869
|
|
POST
|
Hmmm. I couldn't reproduce your error, and I have no idea what could cause it, the UpdateCursor part is OK. General tips: your lines 8-12 don't do anything you use 4 for loops (lines 20, 23, 39, 55) that basically loop over the same data. you can just do it in 1. Try using InsertCursor instead: import arcpy
from pathlib import Path
IMAGE_FOLDER = Path(r"\\...\InspectionServicesData\DRONE_INSPECTION_SERVICE\01_Projects\...\2_FIELD-WORK\DATA-DUMP\2022-08-13...\DJI_202208131356_022")
output_path = r"C:\Users\...\OneDrive...\Desktop\EXIF_TEST\"
output_name = "output_shpdata.shp"
spatial_ref = arcpy.env.outputCoordinateSystem = arcpy.SpatialReference(4326)
# create the ouput shape file and add fields
out_shp = arcpy.management.CreateFeatureclass(output_path, output_name, "POINT", spatial_reference=spatial_ref)
arcpy.management.AddField(out_shp, "Name", "TEXT")
arcpy.management.AddField(out_shp, "Distance", "DOUBLE")
arcpy.management.AddField(out_shp, "YawDegree", "FLOAT")
arcpy.management.AddField(out_shp, "ImagePath", "TEXT")
arcpy.management.AddField(out_shp, "Long", "DOUBLE")
arcpy.management.AddField(out_shp, "Lat", "DOUBLE")
# start the InsertCursor
with arcpy.da.InsertCursor(out_shp, ["SHAPE@", "Name", "Distance", "YawDegree", "ImagePath", "Long", "Lat"]) as cursor:
# loop through the image files
for image in IMAGE_FOLDER.glob("*.jpg"):
# extract exif properties
target_data = arcpy.GetImageEXIFProperties(image)[3]
long = target_data['XMP:drone-dji:LRFTargetLon']
lat = target_data['XMP:drone-dji:LRFTargetLat']
dist = target_data['XMP:drone-dji:LRFTargetDistance']
gimbalyaw = target_data['XMP:drone-dji:GimbalYawDegree']
# create the point geometry
geo_wgs84 = arcpy.PointGeometry(arcpy.Point(long, lat), arcpy.SpatialReference(4326))
geo = geo_wgs84.projectAs(spatial_ref)
# insert the values
row = [geo, image.name, dist, gimbalyaw, str(image), long, lat]
cursor.insertRow(row)
... View more
09-28-2022
03:41 AM
|
2
|
1
|
3059
|
|
POST
|
I don't really understand the question here. What values would you expect in this situation?
... View more
09-28-2022
03:31 AM
|
0
|
2
|
3683
|
|
POST
|
It's very hard to read your script in plain text. Please post it formatted as code:
... View more
09-27-2022
11:38 AM
|
0
|
1
|
3101
|
|
POST
|
I have the same problem In fact, it's exactly the same problem, this is your thread... Sadly, I'm as unqualified as before. I don't know anything about JS. I guess you couldn't find help in the JS Community? I am qualified to look at your Arcade expression (it's different from the one you posted earlier), and I'm not sure what you're trying to achieve. var d = Dictionary()
if($feature.AuthorizationNotice == null) {
d['QuantityActual'] = $feature.Status
d['Assessor'] = $feature.DueDate
return d
} Here's what your expression does: if AuthorizationNotice is null, return a dictionary if AuthorizationNotice is not null, return null Is this the intended behavior?
... View more
09-27-2022
11:29 AM
|
0
|
0
|
2231
|
|
POST
|
Oh, I should have clarified that: I'm just defining some example data to work with there. The "real" script starts at line 21, but instead of converting the input data to a Featureset, you would load your data from the Portal or ArcGIS Online: var methaneReport = FeaturesetByPortalItem(Portal("https://portal.url"), "service-guid", "layer-id")
... View more
09-26-2022
09:38 PM
|
0
|
0
|
1285
|
|
POST
|
Is it the same as you? Nope, I can open both layers without problems. I don't know what the cause for your problem could be, but you could always just use the second method...
... View more
09-26-2022
07:12 AM
|
0
|
0
|
1334
|
|
POST
|
You won't get around a little (might also be a lot) Python for this problem... I can see what I can whip up when I get some time. But first, I need you to clarify some things: Do you need all close perpendicular lines or only the closest perpendicular line? Do you have lines (only 2 vertices) or polylines (multiple vertices)? If polylines: What angle are you looking at? The angle between start and end point? The mean of the angles of every segment? The mean of angles in the 200 meter buffer? Something else? If a line of fc1 is close and perpendicular to multiple lines of fc2, should it be present in the output table multiple times or only once? if only once, which distance and angle should be used?
... View more
09-26-2022
12:30 AM
|
0
|
1
|
2820
|
|
POST
|
Hmm, works for me. Save this script as a Python file in your project folder and run it: import arcpy
aprx_name = "Admin.aprx"
map_name = "Test"
lyr_name = "New Group Layer"
aprx = arcpy.mp.ArcGISProject(aprx_name)
m = aprx.listMaps(map_name)[0]
lyr = m.listLayers(lyr_name)[0]
arcpy.management.SaveToLayerFile(lyr, "test1.lyrx")
lyr.saveACopy("test2.lyrx")
... View more
09-26-2022
12:06 AM
|
0
|
2
|
1344
|
|
POST
|
Both tools reduce the file size of the gdb. Compress reduces the space that the gdb (or single feature classes) needs on the hard drive. This is done by saving the table/gdb in a different (smaller), read-only format. Compact defragmentizes the gdb. While that can change the size of the gdb, this change is due to the gdb using the space on the hard drive more efficiently, not any actual reduction of size. Equivalents in your operating systems (in purpose, not in implementation) would be: Compress: generating a zip file Compact: defragmenting your hard drive You should use Compact from time to time, especially if you do lots of work in the gdb. Not only does it reduce file size, but it should also make reading and writing somewhat faster. EDIT: This is only useful for HDDs. SSDs don't get faster when you defragment them. Compress seems like a relic from a time when file size mattered much more. It's a way to archive a gdb when you don't need to write to it anymore. It can reduce the size of the gdb by huge amounts, but disc space is cheap now, so you don't neccessarily need this tool.
... View more
09-25-2022
11:37 PM
|
4
|
0
|
1721
|
|
POST
|
def get_missing_groups(values):
if not values:
return []
# get the missing values
val_range = range(1, max(values))
missing_vals = sorted(list(set(val_range) - set(values)))
# get the differences between the missing values
differences = [missing_vals[i] - missing_vals[i-1] for i in range(1, len(missing_vals))]
# group up
missing_groups = []
start = None
i_max = len(differences) - 1
for i, k in enumerate(missing_vals):
if start is None:
start = k
if i > i_max or differences[i] > 1:
missing_groups.append([start, k])
start = None
return missing_groups
# some tests
get_missing_groups([1, 2, 5, 6, 10, 11, 20])
# [[3, 4], [7, 9], [12, 19]]
get_missing_groups([5, 6, 10, 178])
# [[1, 4], [7, 9], [11, 177]]
get_missing_groups([])
# []
get_missing_groups(range(20))
# []
# get the groups missing in the table
values = [row[0] for row in arcpy.da.SearchCursor("Table", ["Field"])]
get_missing_groups(values)
... View more
09-23-2022
02:31 PM
|
1
|
0
|
4360
|
|
POST
|
AFAIK, AGOL doesn't support Attribute Rules, yet. You could try publishing to Portal, if you have one.
... View more
09-23-2022
01:33 PM
|
0
|
0
|
1812
|
|
POST
|
Does this do what you want? Open the Python window: Copy and paste this script, hit enter twice: # create the output feature class
route_stops = arcpy.management.CreateFeatureclass("memory", "RouteStops", "POINT")
arcpy.management.AddField(route_stops, "stop_id","LONG")
arcpy.management.AddField(route_stops, "route","TEXT")
# start inserting into the new fc
with arcpy.da.InsertCursor(route_stops, ["SHAPE@", "stop_id", "route"]) as i_cursor:
# loop through the stops
with arcpy.da.SearchCursor("bus_stops", ["SHAPE@", "stop_id", "stop_desc"]) as s_cursor:
for shp, id, desc in s_cursor:
# extract the routes from the field stop_desc:
# delete spaces, get everthing after "routes:" and split that at "/"
routes = desc.replace(" ", "").split("routes:")[-1].split("/")
# for each route, write a point into the new fc
for route in routes:
i_cursor.insertRow([shp, id, route]) This will create a feature class in RAM (so export it if you want to keep it). This feature class will have two fields: The stop_id and the route. It will have a point for each route at each stop. So in your example, it will have 3 overlapping points for stop_id 12143, one for each of the routes 1, 5, and 10.
... View more
09-22-2022
11:50 PM
|
3
|
0
|
1289
|
|
POST
|
To post code: You're using combinedDict as input for Filter() and Max(). This is wrong, because these functions work on FeatureSets, combinedDict is a Dictionary combinedDict is your output, you need to use your input (MethaneReport). To get the date 1 month ago, use DateAdd(baseDate, -1, "months") Max() only works for numbers. If your date column is Text (as the name DateText implies), it will return NaN. To get the most current date, you could use First(OrderBy(methaneReport, "DateText DESC")), but this will lead to problems if your date is a text value, because text values are sorted differently "02/04/2022" > "01/05/2022" this will lead to problems if the values of the devices are collected on different days "Due to the software that our field team uses, the date information is captured with a time stamp." Does this mean that the date field doesn't look like in your table but rather like this: "01/04/2022 10:25:59"? Then your Filter() statement won't work, because "01/04/2022" != "01/04/2022 10:25:59" Assuming your input layer looks like this: // https://community.esri.com/t5/arcgis-online-questions/problem-with-defining-variables-with-multiple/m-p/1214482#M47979
var input = {
geometryType: "",
fields: [
{name: "Device_ID", type: "esriFieldTypeString"},
{name: "DateText", type: "esriFieldTypeString"},
{name: "Chemical", type: "esriFieldTypeDouble"},
],
features:[
{attributes: {Device_ID: "A1", DateText: Text(DateAdd(Now(), -1, "months"), "DD/MM/YYYY hh:mm:ss"), Chemical: 50}},
{attributes: {Device_ID: "A2", DateText: Text(DateAdd(Now(), -1, "months"), "DD/MM/YYYY hh:mm:ss"), Chemical: 49.8}},
{attributes: {Device_ID: "A3", DateText: Text(DateAdd(Now(), -1, "months"), "DD/MM/YYYY hh:mm:ss"), Chemical: 51.2}},
{attributes: {Device_ID: "A1", DateText: Text(Now(), "DD/MM/YYYY hh:mm:ss"), Chemical: 49.2}},
{attributes: {Device_ID: "A2", DateText: Text(Now(), "DD/MM/YYYY hh:mm:ss"), Chemical: 51.2}},
{attributes: {Device_ID: "A3", DateText: Text(Now(), "DD/MM/YYYY hh:mm:ss"), Chemical: 48.2}},
]
}
// load your input data
var methaneReport = Featureset(Text(input))
// filter out the unwanted devices
methaneReport = Filter(methaneReport, "Device_ID NOT IN ('A4', 'A5', 'A6')")
// get all Device_IDs
var devices = OrderBy(Distinct(methaneReport, "Device_ID"), "Device_ID")
// define the output
var outputDict = {
geometryType: "",
fields: [
{name: "Device_ID", type: "esriFieldTypeString"},
{name: "DateText", type: "esriFieldTypeString"},
{name: "Chemical", type: "esriFieldTypeDouble"},
{name: "Change", type: "esriFieldTypeDouble"},
{name: "ListLabel", type: "esriFieldTypeString"},
],
features:[]
}
// define a function to convert your date format to an actual date
function textToDate(textVal) {
// assuming your format is "DD/MM/YYYY hh:mm:ss"
var dateVal = Split(textVal, " ")[0]
var dateSplit = Split(dateVal, "/")
var dd = Number(dateSplit[0])
var mm = Number(dateSplit[1]) - 1 // month starts at 0
var yy = Number(dateSplit[2])
return Date(yy, mm, dd)
}
// define a function that sorts an array of [ [Date, Chemical] ]
// see https://developers.arcgis.com/arcade/function-reference/data_functions/#sort
function sortByDate(a, b) {
return a[0] > b[0]
}
// loop through the Devices
for(var device in devices) {
var deviceID = device.Device_ID
// get all measurements for this device
var deviceMeasurements = Filter(methaneReport, "Device_ID = @deviceID")
// sort the measurements by date
// because DateText is a text field, we can't simply oder by DateText
// instead we have to extract DateText (converted to date) and Chemical and sort that array
var values = []
for(var m in deviceMeasurements) {
Push(values, [textToDate(m.DateText), m.Chemical])
}
var sortedValues = Sort(values, sortByDate)
// fill in the output dict
var prev = sortedValues[0][1]
for(var i in sortedValues) {
var dateText = Text(sortedValues[i][0], "YYYY-MM-DD")
var chemical = sortedValues[i][1]
var change = Round(chemical - prev, 2)
var changeText = "(" + When(change == 0, "-", change > 0, "+" + change, change) + ")"
var newFeature = {attributes: {
Device_ID: deviceID,
DateText: dateText,
Chemical: chemical,
Change: change,
ListLabel: Concatenate([deviceID, dateText, chemical, changeText], "\t")
}}
Push(outputDict.features, newFeature)
prev = chemical
}
}
// convert the dictionary to a featureset and return
return Featureset(Text(outputDict))
... View more
09-21-2022
06:46 AM
|
0
|
0
|
1310
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 01-30-2023 09:57 AM | |
| 1 | 05-18-2023 12:51 AM | |
| 1 | 03-05-2023 12:46 PM | |
| 1 | 12-07-2022 07:01 AM | |
| 1 | 06-21-2022 08:27 AM |
| Online Status |
Offline
|
| Date Last Visited |
02-03-2024
06:14 PM
|