|
BLOG
|
Is there any plan or schedule for the toolkit to be updated. At this point the latest version is 100.4 almost three months after 100.6 has been released. I would love to just use the code, but as I have never been able to get it to actually build that is not possible either. Thanks -Joe
... View more
10-15-2019
01:24 PM
|
0
|
0
|
3525
|
|
POST
|
I think, and don't have an example... But you would use: ArcGISPortal.FindUsersAsync Method (PortalQueryParameters). The trick is you need to set the Query on the PortalQueryParameters correctly PortalQueryParameters.Query Property. This is based on the portal API query strings User Search—ArcGIS REST API: Users, groups, and content | ArcGIS for Developers . Not sure why the method to get groups from the item does not just give you an easy to work with enumeration of Groups instead of the convoluted way it seems to work
... View more
10-03-2019
09:10 AM
|
0
|
1
|
1278
|
|
POST
|
When I try to add the row to the table I get a null exception because a non-null field is not being set to the default value. I have code that loops through the PrototypeAttributes to set all those attributes but there are some that are not included even though they have a default value. We are using the UPDM 2019 data model not a model we created ourselves await feature.FeatureTable.AddFeatureAsync(feature); {Esri.ArcGISRuntime.ArcGISRuntimeException: Cannot extract a null row value. Call is_null to check.: lifecyclestatus cannot be null. Encountered on feature with ID of -9223372036854775808. at Esri.ArcGISRuntime.ArcGISException.HandleCoreError (RuntimeCoreNet.GeneratedWrappers.CoreError error, System.Boolean throwException) [0x00013] in <08b2a841d4d34b638c69bf9e3f231de6>:0 at RuntimeCoreNet.GeneratedWrappers.Interop.CheckError (System.IntPtr errorHandle, System.Boolean throwOnFailure, System.Runtime.InteropServices.GCHandle wrapperHandle) [0x0002e] in <08b2a841d4d34b638c69bf9e3f231de6>:0 at RuntimeCoreNet.GeneratedWrappers.CoreTask.Get () [0x00019] in <08b2a841d4d34b638c69bf9e3f231de6>:0 at Esri.ArcGISRuntime.Internal.CoreTaskExtensions+TaskCompletedCallbackHandler`1 .OnCompleted (System.Object sender, System.EventArgs e) [0x00034] in <08b2a841d4d34b638c69bf9e3f231de6>:0 --- End of stack trace from previous location where exception was thrown --- at Esri.ArcGISRuntime.Internal.CoreTaskExtensions+TaskCompletedCallbackHandler`1 .CreateInternal (RuntimeCoreNet.GeneratedWrappers.CoreTask task, System.Threading.CancellationToken cancellationToken) [0x0007f] in <08b2a841d4d34b638c69bf9e3f231de6>:0 at Esri.ArcGISRuntime.Data.FeatureTable.AddFeatureAsync (Esri.ArcGISRuntime.Data.Feature feature) [0x0008f] in <08b2a841d4d34b638c69bf9e3f231de6>:0 at Mobile.AsBuilt.Framework.EditTools.EditBaseViewModel.CompleteFeatureSubmitted (Mobile.AsBuilt.Framework.Events.FeatureSubmittedEventArgs args) [0x000cb] in D:\repos\ramtech-client-png\as-built-xamarin\src\Mobile.AsBuilt.Framework\EditTools\EditBaseViewModel.cs:584 } {
"name" : "lifecyclestatus",
"type" : "esriFieldTypeSmallInteger",
"alias" : "Life Cycle Status",
"sqlType" : "sqlTypeOther",
"nullable" : false,
"editable" : true,
"domain" :
{
"type" : "codedValue",
"name" : "Pipeline_Lifecycle_Combined",
"codedValues" : [
{
"name" : "Unknown",
"code" : 0
},
{
"name" : "Proposed",
"code" : 1
},
{
"name" : "Approved",
"code" : 2
},
{
"name" : "Proposed and Approved",
"code" : 3
},
{
"name" : "Under Construction",
"code" : 4
},
{
"name" : "Approved and Under Construction",
"code" : 6
},
{
"name" : "Proposed, Approved and Under Construction",
"code" : 7
},
{
"name" : "In Service",
"code" : 8
},
{
"name" : "In Service and Under Construction",
"code" : 12
},
{
"name" : "In Service, Under Construction, and Approved",
"code" : 14
},
{
"name" : "In Service, Under Construction, Approved and Proposed",
"code" : 15
},
{
"name" : "To Be Retired",
"code" : 16
},
{
"name" : "In Service and To Be Retired",
"code" : 24
},
{
"name" : "Abandoned",
"code" : 32
},
{
"name" : "Retired",
"code" : 64
},
{
"name" : "Removed",
"code" : 128
},
{
"name" : "Out of Service",
"code" : 256
}
]
},
"defaultValue" : 8
}
... View more
10-02-2019
03:58 PM
|
0
|
0
|
1528
|
|
POST
|
We have some layers created in AGOL. These table have default values that are assigned to the field. These are not assigned to the feature template so they do not show up as PrototypeAttributes. Is it possible to find these values? Right now the only thing I can see is to parse the service definition json, which is more involved then I would like Thanks -Joe
... View more
10-02-2019
03:15 PM
|
2
|
2
|
1690
|
|
POST
|
There was a similar thread a few days ago, https://community.esri.com/thread/240359-how-to-get-satellite-info-net-wpf-1005 I would check out GitHub - dotMorten/NmeaParser: Library for handling NMEA message in Windows Desktop, Store, Phone, Universal, and Xamari… by Morten Nielsen
... View more
09-24-2019
07:35 AM
|
2
|
1
|
2089
|
|
POST
|
Sorry for misinterpretation, and I agree. I think the same could be said of most any type of development. Without a forum like Stack Overflow I would not have been able to solve a nearly infinite number of problems I had in WPF. Documentation can only go so far, and will in most cases only address the most fundamental use case and leave it to the developer to take it the next step.
... View more
09-20-2019
01:11 PM
|
0
|
0
|
3013
|
|
POST
|
This is a BluetoothLocationDataSource that was written for a WPF application a while back. It uses the 32feet library previously mentioned for connectivity and the dotMorten/NmeaParser (thanks Morten Nielsen) There is code specific to the framework used in the application, but I think you could extract the primary logic. Note: Not 100% sure on my computation of Accuracy, I have done research on this topic and found differing computations of overall sigma. As a side note, accuracy is a bit of a nebulous term, what this really means is there is a certain % chance (usually 95%) that a point falls within a radius of the location given. public class BluetoothLocationDataSource : LocationDataSource
{
private ILog4NetFacade Log { get; }
#region Private Fields
private bool _isTryingToOpen;
private MapPoint _mapPoint;
private double _velocity, _course, _accuracy;
#endregion
public BluetoothLocationDataSource(IEventAggregator eventAggregator, ILog4NetFacade log)
{
Log = log;
EventAggregator = eventAggregator;
EventAggregator.GetEvent<SendNTripCorrectionEvent>().Subscribe(OnSendNTripCorrection);
}
protected IEventAggregator EventAggregator { get; }
protected BluetoothClient BluetoothClient { get; set; }
public BluetoothDeviceInfo BluetoothDevice { get; set; }
protected override async Task OnStartAsync()
{
try
{
//Don't want to come back in if we are still trying to open port
if ( _isTryingToOpen ) return;
if ( IsStarted ) return;
BluetoothClient = new BluetoothClient();
var devices = await BluetoothClient.DiscoverDevicesAsync(5, true, true, false);
Log.Debug($"Bluetooth found devices: {devices.Length}");
for (var i = 0; i < devices.Length; i++)
{
var device = devices[i];
Log.Debug($"Device {i}: Device Name: {device.DeviceName}");
Log.Debug($"Device {i}: Device Class: {device.ClassOfDevice.Device} {device.ClassOfDevice.Service}");
Log.Debug($"Device {i}: Service Class: {device.ClassOfDevice.Service}");
}
//BluetoothDevice = devices.FirstOrDefault(d => d.ClassOfDevice.Equals(new ClassOfDevice(DeviceClass.Miscellaneous, ServiceClass.Positioning)) && d.DeviceName.IndexOf("SXBlue", StringComparison.CurrentCultureIgnoreCase) > 0);
BluetoothDevice = devices.FirstOrDefault(d => d.ClassOfDevice.Equals(new ClassOfDevice(DeviceClass.Miscellaneous, ServiceClass.Positioning)));
if (BluetoothDevice == null)
{
Log.Debug("Bluetooth device not found");
throw new Exception("Unable to locate bluetooth device");
}
Log.Debug("Bluetooth device found");
if ( !BluetoothDevice.InstalledServices.Contains(BluetoothService.SerialPort) )
{
Log.Debug("Bluetooth device does not contain Serial Port Service");
throw new Exception("Bluetooth device is not valid for this LocationDataSource");
}
Log.Debug("Bluetooth device contains SerialPort service");
_isTryingToOpen = true;
if ( !await OpenPort() )
{
Log.Debug("Unable to Open Bluetooth port");
EventAggregator.GetEvent<GpsConnectCompleteEvent>().Publish(new GpsConnectCompleteEventArgs { ConnectSuccess = false });
return;
}
var _ = ReceiveData();
EventAggregator.GetEvent<GpsConnectCompleteEvent>().Publish(new GpsConnectCompleteEventArgs { ConnectSuccess = true });
}
catch (Exception e)
{
Log.Error(e.Message, e);
// ReSharper disable once PossibleIntendedRethrow
throw e;
}
}
private async Task<bool> OpenPort()
{
for (int i = 0; i < 5; i++)
{
try
{
await BluetoothClient.ConnectAsync(BluetoothDevice.DeviceAddress, BluetoothService.SerialPort);
if ( !BluetoothClient.Connected ) throw new Exception();
Log.Debug($"Bluetooth port opened after {i} attempts");
_isTryingToOpen = false;
return true;
}
catch (Exception)
{
//continue;
}
}
_isTryingToOpen = false;
return false;
}
public void SendMessage()
{
var b = Encoding.ASCII.GetBytes("$JT\r\n");
BluetoothClient.Client.Send(b);
}
private async Task ReceiveData()
{
byte[] bytesReceived = new byte[256];
string result = string.Empty;
do
{
var bytes = 0;
try
{
bytes = await BluetoothClient.Client.ReceiveAsync(bytesReceived, 0, 256, SocketFlags.None);
}
//exception handlers both do same thing but wanted to know if it is socket exception
catch (SocketException e)
{
Log.Error("Stopped receiving bluetooth data due to scoket exception");
Log.Error(e.Message);
//stopped recieving data so going to try and see if we can reconnect
_isTryingToOpen = false;
EventAggregator.GetEvent<GpsConnectCompleteEvent>().Publish(new GpsConnectCompleteEventArgs { ConnectSuccess = false });
break;
}
catch (Exception e)
{
Log.Error("Stopped receiving bluetooth data");
Log.Error(e.Message, e);
//Not receiving data and Socket resets
EventAggregator.GetEvent<GpsConnectCompleteEvent>().Publish(new GpsConnectCompleteEventArgs { ConnectSuccess = false });
break;
}
result = result + Encoding.ASCII.GetString(bytesReceived, 0, bytes);
if ( bytes < 10 ) continue;
string[] lines = result.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
for (var index = 0; index < lines.Length - 1; index++)
{
//split data into lines at this \r\n
var line = lines[index];
if ( line.StartsWith("$>") )
{
//TODO: This is a response
}
UpdateLocationFromNemaSentence(line);
}
result = lines.Last();
} while (true);
}
private void UpdateLocationFromNemaSentence(string line)
{
try
{
line = line.TrimEnd('\n', '\r');
var message = NmeaMessage.Parse(line);
ReadLocationAttributesFromMessage(message);
}
catch (Exception)
{
//
}
if ( _mapPoint == null || double.IsNaN(_mapPoint.X) || double.IsNaN(_mapPoint.Y) )
{
UpdateLastKnownLocation();
return;
}
UpdateLocation(new Esri.ArcGISRuntime.Location.Location(_mapPoint, _accuracy, _velocity, _course, false));
}
private void ReadLocationAttributesFromMessage(NmeaMessage message)
{
switch (message)
{
case Gpgga gpgga:
_mapPoint = new MapPoint(gpgga.Longitude, gpgga.Latitude, SpatialReference.Create(4326));
EventAggregator.GetEvent<UpdateLastGgaEvent>().Publish(gpgga.ToString());
break;
case Gpgsa gpgsa:
break;
case Gprmc gprmc:
_velocity = double.IsNaN(gprmc.Speed) ? 0 : gprmc.Speed * 0.5144; //knots to m\s
_course = double.IsNaN(gprmc.Course) ? 0 : gprmc.Course;
_mapPoint = new MapPoint(gprmc.Longitude, gprmc.Latitude, SpatialReference.Create(4326));
break;
case Gpgsv gpgsv:
break;
case Gpgst gpgst:
double latError = gpgst.SigmaLatitudeError;
double lonError = gpgst.SigmaLongitudeError;
_accuracy = Math.Sqrt(0.5 * (Math.Pow(latError, 2) + Math.Pow(lonError, 2)));
break;
}
}
private void UpdateLastKnownLocation()
{
//If latest point not valid send previous point as LastKnown
if ( _mapPoint == null )
{
_mapPoint = new MapPoint(double.NaN, double.NaN, SpatialReferences.Wgs84);
}
UpdateLocation(new Esri.ArcGISRuntime.Location.Location(_mapPoint, _accuracy, _velocity, _course, true));
}
protected override Task OnStopAsync()
{
BluetoothClient?.Client?.Close(250);
BluetoothClient?.Close();
BluetoothClient = null;
return Task.FromResult(true);
}
private async void OnSendNTripCorrection(SendNTripCorrectionEventArgs obj)
{
try
{
await BluetoothClient.Client.SendAsync(obj.Bytes);
}
catch (Exception e)
{
Log.Error(e.Message, e);
}
}
}
... View more
09-20-2019
09:38 AM
|
2
|
1
|
3095
|
|
POST
|
I will agree that the documentation of ArcGISFeature:LoadAsync is lacking and the sample that does exist is not giving any indication of the purpose of the method However, and not to be rude, GeoNet is a forum for community collaboration, not sure what you mean by lack of message board. You received a response to your question within a day and it actually relates back very closely to a previously asked and answered question. So I think this forum served you well and achieved it's purpose.
... View more
09-20-2019
09:06 AM
|
0
|
2
|
3013
|
|
POST
|
Call Feature.LoadAsync() https://community.esri.com/thread/236680-get-attributes-from-featurelayergetselectedfeaturesasync
... View more
09-19-2019
03:39 PM
|
0
|
4
|
3013
|
|
POST
|
Yes, but the Layer object is in a different OperationalLayers collection. It is not that you have created a new LayerCollection. You have to remove the layer from the first map in order to add it to the new map. This is a sample to how the basemap was switched out and the layers had to be removed and add anew private void ResetMapLayers(Map map)
{
LayerCollection operationalLayers = new LayerCollection();
Layer[] tempLayers = new Layer[_map.OperationalLayers.Count];
_map.OperationalLayers.CopyTo(tempLayers, 0);
foreach (var operationalLayer in tempLayers)
{
_map.OperationalLayers.Remove(operationalLayer);
operationalLayers.Add(operationalLayer);
}
_map.OperationalLayers.Clear();
Envelope extent = _mapViewSettings.VisibleExtent; // MapViewController.MapView.VisibleArea.Extent;
map.InitialViewpoint = new Viewpoint(extent);
map.OperationalLayers = operationalLayers;
map.Basemap.BaseLayers[0].Name = "Basemap";
_map = map;
_eventAggregator.GetEvent<MapLoadedEvent>().Publish(new MapLoadedEventArgs(_map));
}
... View more
09-18-2019
12:11 PM
|
1
|
1
|
4492
|
|
POST
|
Morten Nielsen may have upgraded some stuff since the last time I went through setting up things in Windows. The library does not have bluetooth support in WPF. WPF does not have native bluetooth support. There are external bluetooth libraries (e.g., GitHub - inthehand/32feet: Personal Area Networking for .NET ) which will work for WPF, but native API support does not exist, you need UWP for that. Many external GPS units will mimic a serial connection and in this case it is possible to use Morten's SerialPortDevice. However, you still do need to create a LocationDataSource in Runtime to use as the DataSource on the LocationProvider. Using the 32feet library it is possible to create a receiver for the signal over bluetooth in WPF.
... View more
09-18-2019
12:00 PM
|
2
|
0
|
3095
|
|
POST
|
Also one thing to consider: IMHO the purist MVVM approach where absolutely no code-behind can ever exist isn't really true to what MVVM is saying. You can have code-behind, as long as that code-behind is view-specific. YES!. And in a large application I think this is absolutely required (certainly with Runtime it is). Here is how we do something like changing viewpoint. This code is in the MapViews Code behind. Zoom is done from anywhere in the application by firing a SetViewpointEvent private async void OnSetViewpoint(SetViewpointEventArgs args)
{
//First see if a viewpoint was sent, otherwise use a geometry
try
{
if ( args.Viewpoint != null )
{
await MapView.SetViewpointAsync(args.Viewpoint, TimeSpan.FromMilliseconds(750));
return;
}
var geometry = args.Geometry;
switch (geometry)
{
case MapPoint mapPoint:
if (MapView.MapScale < args.Scale)
{
await MapView.SetViewpointCenterAsync(mapPoint);
}
else
{
await MapView.SetViewpointCenterAsync(mapPoint, args.Scale);
}
break;
case Polyline polyline:
{
var envelope = polyline.Extent;
var buffer = GeometryEngine.Buffer(envelope, 1000);
var viewpoint = new Viewpoint(buffer);
await MapView.SetViewpointAsync(viewpoint, TimeSpan.FromMilliseconds(750));
break;
}
case Polygon polygon:
await MapView.SetViewpointGeometryAsync(polygon.Extent, args.Padding);
break;
case Envelope envelope:
await MapView.SetViewpointGeometryAsync(envelope);
break;
}
}
catch (Exception e)
{
_log.Error(e.Message, e);
}
} We do similar stuff with displaying popups, saving screen images, and functions that are exposed by the MapView object
... View more
09-13-2019
11:27 AM
|
1
|
0
|
2147
|
|
POST
|
After many headaches I was able to track down that the way I was receiving and parsing the data stream from the external unit on a background thread was not working as expected. What was happening was that sentences were getting lost and not sent over to the LocationDataSource implementation. For some reason it seems like the GGA and RMC sentences got lost the most often (although I think just some random math because there are so many GSV sentences in relation to everything else). I was able to change this around so now all sentences get passed in to the LocationDataSource implementation and things seem to be behaving. I was originally using an approach I took from WPF, but enough differences in how iOS ExternalAccessory processes compared to bluetooth in WPF that additional changes were required Thanks Joe
... View more
09-13-2019
11:08 AM
|
0
|
0
|
1608
|
|
POST
|
I won't get into a philosophical discussion, but I don't consider the Controller approach as MVVM, it is simply a clean way to expose MapView outside the view that contains it. There is an old discussion about this Accessing MapView methods like IdentifyGraphicsOverlaysAsync from viewmodel. In there is a way that I have used a TriggerAction to attach Identify behavior to the MapView. It then uses eventing to send results to the rest of the application. I have written a very large scale enterprise application consisting of over a dozen separate modules and been almost completely able to avoid having to share the MapView. The one issue is with a module that uses the TOC toolbox control which requires the MapView and in there the controller approach was used to pass the MapView. Everything else can be done using event publish/subscribe from the code behind of the view containing the MapView. I agree with your initial statement, to me the MapView provides too much functionality and really hampers building a nice MVVM structure. It (literally) took me years to work through all the various places I required MapView methods and organize them in what I consider a clean MVVM manner where the remainder of the application has no knowledge of the MapView (excluding the TOC issue)
... View more
09-13-2019
05:51 AM
|
0
|
0
|
2147
|
|
POST
|
There is nothing wrong with this approach, but as I mentioned in my previous post it does not scale to a large application that may need access to a MapView event from an object that is not bound directly MapViews view. Using an event approach one can respond to a MapView event from anywhere, even a separate .dll. Again not a bad approach, but does not scale to a really large application.
... View more
09-03-2019
06:41 AM
|
2
|
0
|
7256
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 05-11-2026 09:07 AM | |
| 1 | 10-23-2025 12:16 PM | |
| 1 | 10-19-2022 01:08 PM | |
| 1 | 09-03-2025 09:25 AM | |
| 1 | 04-16-2025 12:37 PM |
| Online Status |
Offline
|
| Date Last Visited |
4 weeks ago
|