IDEA
|
Hi @OhioGIS , At least for now, I have to defer to the ESRI product team around any plans around Flutter support. I wish I could say more. In the meantime, our team has been contributing to @snlasystem's arcgis_maps_flutter package. We also have a current contract with ESRI for some additional contributions/enhancements. We have been very pleased with this package. Best, Jake
... View more
11-20-2023
04:44 PM
|
0
|
0
|
843
|
IDEA
|
@MichaelMoor @SoniaGupta I figured I'd provide a quick update. @snlasystem is building a Flutter plugin that I have had a ton of success with. I am rewriting our native iOS and Android fishing regulation apps thanks to this plugin. A single code base. The same application logic for both platforms. A lot less code. And I only have to write one UI and tweak it where I want to for each platform. Because the plugin is a wrapper for the native SDKs, the performance is really good. This is the plugin esri should be supporting. Here is the repo: https://github.com/valentingrigorean/arcgis_maps_flutter
... View more
11-09-2022
08:31 AM
|
0
|
0
|
1885
|
POST
|
Hello, I figured I would take a minute to provide an update on this. I have been leveraging this plugin to rewrite our native iOS and Android fishing regulation apps in a single code base, with the same application logic (huge win!). Also, with Flutter, unlike some other cross-platform frameworks, I only have to write a single UI, and (optionally) tweak platform-specific widgets, thanks to this plugin. I would also note the developers are super responsive and quick to fix any bugs. This plugin meets 90+% of my app's needs at this point. I have bundled a replica.geodatabase file for offline data access. I am adding downloading and syncing (via ImportDelta) a delta.geodatabase file. It looks like the plugin already supports this. It also looks like it supports offline .tpk and .vtpk basemaps, currently. I will be adding a bundled .vtpk shortly. Just wanted to say thank you! This is the plugin ESRI should start supporting. Best, Jake
... View more
11-09-2022
08:17 AM
|
0
|
0
|
1121
|
POST
|
Hello @snlasystem , I really appreciate you reaching out. I am very interested in taking a closer look. Have you published it to pub.dev or is it available elsewhere? Feel free to DM me, if you'd prefer. Best, Jake
... View more
05-16-2022
01:28 PM
|
0
|
1
|
4525
|
POST
|
Hi @TrevorFrame , I appreciate the reply. Unfortunately, AppStudio really isn't a solution for us. Our apps are highly-customized and interact with our in-house APIs. Even the way we leverage ArcGIS Server (per the Enterprise team) is novel. Ideally, ESRI would start supporting Flutter, to support the huge, growing community. Best, Jake
... View more
05-16-2022
01:19 PM
|
0
|
0
|
1351
|
IDEA
|
I totally agree on the need for Flutter support. Xamarin pales in comparison to Flutter, in terms of performance, support, community and popularity. Any updates on this? In my last conversation with ESRI SDK product management, there was no plan to support Flutter. I hope this has changed, or will in the very near future. My mobile dev team has had tremendous success with Flutter. Setting aside for the moment that we don't have to maintain 2 (or more) code bases for each app, it takes about half the time to write an app in Flutter vs. native. We are in the process of rewriting almost all apps in Flutter. If there is not a plan for ESRI to support Flutter, we will need to migrate away from ESRI and ArcGIS.
... View more
03-15-2022
02:35 PM
|
0
|
0
|
2468
|
POST
|
Any updates on this? In my last conversation with ESRI SDK product management, there was no plan to support Flutter. I hope this has changed, or will in the very near future. My mobile dev team has had tremendous success with Flutter. Setting aside for the moment that we don't have to maintain 2 (or more) code bases for each app, it takes about half the time to write an app in Flutter vs. native. We are in the process of rewriting almost all apps in Flutter. The app with our largest customer base (over 200k) is currently leveraging the runtime SDKs. If there is not a plan for ESRI to support Flutter, we will need to migrate away from ESRI and ArcGIS.
... View more
03-15-2022
02:32 PM
|
0
|
8
|
4784
|
POST
|
Hi Nick, I rendered the ereg feature layer red temporarily to better visualize what may be happening. Interestingly, 682 features are returned by the query, all of them are within the extent. However, not all of the features within the extent are returned by the query. Jake
... View more
05-12-2020
08:23 AM
|
0
|
1
|
3989
|
POST
|
Also, here's a screenshot of what happens when I programmatically select the features returned from the database query (with Deschutes River still selected). Note, the river geometry does not actually intersect with any of these features. Jake
... View more
05-11-2020
05:06 PM
|
0
|
0
|
3989
|
POST
|
Hi Nick, Thank you for the quick response. Yes, it was behaving the same all the way back to 100.2.1. I incrementally updated the SDK from 100.2.1 on Friday. I was guardedly optimistic that it would be resolved at 100.5.0, due to all the reworking of the queries, but no luck. I also wanted to mention that I verified the geometry I get from the tapped feature is a polyline, not an extent just before I assign it to the params.geometry; same with the params.geometry if I read it just before it is passed in the query. So, I'm pretty sure the issue is with the method itself, or the AGSSpatialRelationship enum. I can see the corresponding int values in iOS, but not Android. Cheers, Jake
... View more
05-11-2020
10:38 AM
|
0
|
0
|
3989
|
POST
|
Hi, I would appreciate help on Esri Case #02552078, escalating a hotfix for a bug in queryFeaturesWithParameters:completion: (AGSFeatureTable) that is present in 100.8.0. I recently refactored our Android and iOS apps to support querying stacked geometry for features that intersect or overlap a user-selected (via tap) feature. It is working properly (and as intended according to the documentation) in Android. However, in iOS, the query method appears to be incorrectly using the extent of the geometry, rather than the geometry itself. For example, a query using the Deschutes River returns, among 100s of other results, Packwood Creek, which isn't even in the same drainage. But, it is within the extent of Deschutes River (see screenshots below). For clarification, I am using: params.spatialRelationship = AGSSpatialRelationship.intersects params.maxAllowableOffset = 0 I would appreciate a hotfix for this issue, plus any workaround in the meantime. I am happy to provide additional info. I cannot share the endpoints publicly, but they are attached to the case and I can provide them via DM or email. Cheers, Jake
... View more
05-08-2020
06:20 PM
|
0
|
6
|
4292
|
POST
|
iOS SDK version: 100.2.1 We have a public-facing mobile app with ~40k users. It leverages the runtime geodatabase and imports delta files (sqlite) with the SDK importDeltaWithGeodatabase:deltaPath:completion:() method. This works great almost every time 95+%, but we've started seeing failures due to "Attempt to write a readonly database" error. We have not been able to reproduce it such that we can determine a cause. It would be great if the product team could weigh-in on what circumstances/logic/blocks in the SDK throw this error. We use a modified disconnected workflow, but: a) The mobile client never connects to the service, rather the client downloads a replica.geodatabase (mobile sqlite replica) from AWS S3. b) All edits are one-way, server to client, via a delta.geodatabase (mobile sqlite delta file). c) Edits import just fine, 95+% of the time, and then they don't and we get that error. d) We never set the database to be read-only; nor would we want to, or even know how to. Given these factors, I need to know what other circumstances could cause the SDK to think the database is read-only. Cheers, Jake
... View more
11-14-2018
08:49 AM
|
0
|
1
|
1128
|
POST
|
Hi Michael, We have a similar scenario on a project we're working on. I'm just using an AGSGraphicLayer, rendered on top of the feature layer, to copy the selected feature into temporarily. In your case, once user has selected feature they want: 1) Create either AGSSimpleRenderer or just symbol to make the feature a different color, etc. Here are a couple examples of renderers that illustrate how to do either: var municipalityPointRenderer: AGSSimpleRenderer { let symbol = AGSPictureMarkerSymbol(image: imageLiteral(resourceName: "townSymbol")) symbol.height = 10.0 symbol.width = 10.0 let renderer = AGSSimpleRenderer(symbol: symbol) return renderer } var municipalityPolyRenderer: AGSSimpleRenderer { let lineSymbol = AGSSimpleLineSymbol(style: .solid, color: UIColor(red: 51/255, green: 51/255, blue: 51/255, alpha: 0.0), width: 1) let fillSymbol = AGSSimpleFillSymbol(style: .solid, color: UIColor.clear, outline: lineSymbol) let renderer = AGSSimpleRenderer(symbol: fillSymbol) return renderer } 2) Create a new AGSGraphic from feature. Here is an example, where feature is AGSArcGISFeature from AGSIdentifyLayerResult. Note, that you could assign a symbol here if you weren't using a renderer: let selectedFeature = AGSGraphic(geometry: feature.geometry, symbol: nil, attributes: feature.attributes as? [String : Any]) 3) Create a new AGSGraphicsOverlay, add the graphic from step 2 to it, assign the renderer and add it to the mapView: let selectedLayer = AGSGraphicsOverlay() selectedLayer.graphics.add(selectedFeature) selectedLayer.renderer = EsriUtil.municipalityPointRenderer self.mapView.graphicsOverlays.add(selectedLayer) 4) Remove the overlay when user deselects, or selects another. If you have a single overlay, you can simply remove them all. You will need to adjust based on how your mapView, and overlay are referenced: self?.mapView.graphicsOverlays.removeAllObjects() Hope this helps. Let me know if you have any questions. Cheers, Jake
... View more
10-26-2018
09:42 AM
|
2
|
1
|
659
|
POST
|
This example utilizes 2 separate AGSGraphicOverlay layers, but you could similarly accomplish with a feature layer and a graphic overlay layer. It also uses a custom UIImageView to transition between removing the selected graphic from the one layer, and adding it to the second (selected graphic overlay). It's not quite perfect, but appears to work as desired. Alternatively, you can clone the project (uses CocoaPods and ArcGIS Runtime 100.2.1): // // ViewController.swift // ESRI Scratch // // Created by Jake Shapley on 9/30/18. // Licensed under MIT // import UIKit import ArcGIS class ViewController: UIViewController, AGSCalloutDelegate, AGSGeoViewTouchDelegate { // MARK: Properties @IBOutlet weak var mapView: AGSMapView! var waypointGraphic = AGSGraphic() var selectedWayPointImageView = UIImageView() var wayPointLayer = AGSGraphicsOverlay() var selectedPointLayer = AGSGraphicsOverlay() var lastQuery: AGSCancelable! // MARK: Load override func viewDidLoad() { super.viewDidLoad() self.initMap() } // MARK: Initializers fileprivate func initMap() { let map = AGSMap(basemap: AGSBasemap.lightGrayCanvasVector()) self.mapView.map = map self.mapView.touchDelegate = self self.mapView.setViewpoint(AGSViewpoint(center: AGSPoint(x: -13454510, y: 6071864, spatialReference: AGSSpatialReference.webMercator()), scale: 8000000), completion: nil) self.updateWaypointGeometry() } // MARK: Waypoints fileprivate var waypoints: [(id: String, name: String, loc: CLLocationCoordinate2D)] { get { var points = [(id: String, name: String, loc: CLLocationCoordinate2D)]() points.append((id: "1", name: "Car", loc: CLLocationCoordinate2D(latitude: 46.323, longitude: -123.221))) points.append((id: "2", name: "Park", loc: CLLocationCoordinate2D(latitude: 46.446, longitude: -118.619))) points.append((id: "3", name: "Tree", loc: CLLocationCoordinate2D(latitude: 46.567, longitude: -122.521))) points.append((id: "4", name: "Old House", loc: CLLocationCoordinate2D(latitude: 47.237, longitude: -122.421))) points.append((id: "5", name: "Bird", loc: CLLocationCoordinate2D(latitude: 47.667, longitude: -122.123))) points.append((id: "6", name: "Truck", loc: CLLocationCoordinate2D(latitude: 46.667, longitude: -121.123))) points.append((id: "7", name: "School", loc: CLLocationCoordinate2D(latitude: 48.667, longitude: -119.123))) return points } } fileprivate func updateWaypointGeometry() { self.mapView.graphicsOverlays.remove(self.wayPointLayer) self.wayPointLayer.graphics.removeAllObjects() if waypoints.count > 0 { let wgs84 = AGSSpatialReference.wgs84() let symbol = AGSPictureMarkerSymbol(image: UIImage(named: "waypointMarker")!) symbol.height = 13 symbol.width = 15 symbol.offsetX = 0 symbol.offsetY = 0 for point in waypoints { let id = point.id let name = point.name let attributes = ["id": id, "name": name] let lat = point.loc.latitude let long = point.loc.longitude let loc = AGSPoint(x: long, y: lat, spatialReference: wgs84) let graphic = AGSGraphic(geometry: loc, symbol: symbol, attributes: attributes) self.wayPointLayer.graphics.add(graphic) } self.mapView.graphicsOverlays.add(self.wayPointLayer) } } fileprivate func updateSelectedWaypointGeometry(at point: AGSPoint, attributes: NSMutableDictionary?) -> Void { self.waypointGraphic.isVisible = false self.mapView.graphicsOverlays.remove(self.selectedPointLayer) self.selectedPointLayer.graphics.removeAllObjects() self.selectedWayPointImageView = UIImageView(image: UIImage(named: "waypointFilled")) let cgCenter = self.mapView.location(toScreen: point) let rect = CGRect(x: cgCenter.x - 10.0, y: cgCenter.y - 10.0, width: 20, height: 20) self.selectedWayPointImageView.frame = rect self.view.addSubview(self.selectedWayPointImageView) UIView.animate(withDuration: 0.3, delay: 0.0, options: [.curveEaseInOut], animations: { self.selectedWayPointImageView.transform = CGAffineTransform(scaleX: 1.3, y: 1.8).translatedBy(x: 0, y: -8) } , completion: { _ in let symbol = AGSPictureMarkerSymbol(image: UIImage(named: "waypointFilled")!) symbol.height = 35 symbol.width = 25 symbol.offsetX = 0 symbol.offsetY = 18 let graphic = AGSGraphic(geometry: point, symbol: symbol, attributes: attributes as! [String : Any]) self.selectedPointLayer.graphics.add(graphic) self.mapView.graphicsOverlays.add(self.selectedPointLayer) //sleep(2) DispatchQueue.main.asyncAfter(deadline: (DispatchTime.now() + .milliseconds(200)), execute: { self.selectedWayPointImageView.alpha = 0.0 self.selectedWayPointImageView.removeFromSuperview() }) }) } // MARK: GeoView Touch Delegate func geoView(_ geoView: AGSGeoView, didTapAtScreenPoint screenPoint: CGPoint, mapPoint: AGSPoint) { if let lastQuery = self.lastQuery { lastQuery.cancel() } if waypoints.count > 0 { self.waypointGraphic.isVisible = true self.lastQuery = self.mapView.identify(self.wayPointLayer, screenPoint: screenPoint, tolerance: 8.0, returnPopupsOnly: false, maximumResults: 1, completion: { [weak self] (identifyLayerResult: AGSIdentifyGraphicsOverlayResult?) -> Void in if let graphics = identifyLayerResult?.graphics, graphics.count > 0 { let generator = UISelectionFeedbackGenerator() generator.selectionChanged() self?.waypointGraphic = graphics[0] let attributes = self?.waypointGraphic.attributes let mapPoint = self?.waypointGraphic.geometry?.extent.center self?.updateSelectedWaypointGeometry(at: mapPoint!, attributes: attributes) } else { self?.mapView.graphicsOverlays.remove(self?.selectedPointLayer) self?.selectedPointLayer.graphics.removeAllObjects() } }) } } } Cheers, Jake
... View more
09-30-2018
01:09 PM
|
2
|
0
|
1071
|
POST
|
I've been working on a similar requirement. My observation is the one problem with reassigning the renderer, even with a uniqueValueRenderer, is that all the markers flash off and on. This isn't the best experience. We are starting with a AGSGraphicOverlay, not a feature layer, but solution should be similar. We also have a requirement to animate the marker. I'll share when I'm done, but here are the general steps: 1) Query the graphic overlay (or feature layer) with identify task. 2) Set the visibility of the selected graphic (or feature) to false. 3) Add a custom UIImageView as a sublayer to the mapView, using the mapView.location(toScreen: AGSPoint) to construct a CGRect for the image view frame 4) Animate the image view, in my case, translating to grow, but maintain tip of marker on location 5) Add marker with same final image, size and yOffset to a second graphic overlay 6) Upon new tap, remove the second graphic overlay, optionally re-add and animate down an image view, remove it, and set all graphics in the first graphic overlay to isVisible = true Hope this helps. Cheers, Jake
... View more
09-28-2018
08:54 PM
|
0
|
0
|
1071
|
Title | Kudos | Posted |
---|---|---|
2 | 10-26-2018 09:42 AM | |
2 | 09-30-2018 01:09 PM | |
3 | 09-24-2018 07:16 PM | |
2 | 05-16-2018 08:29 AM | |
2 | 04-03-2018 01:41 PM |
Online Status |
Offline
|
Date Last Visited |
Friday
|