POST
|
If you have ArcGIS Server, it's significantly faster to use that for caching instead, as it's multi-threaded and last time I checked ArcMap caching was not. Publish a service to ArcGIS Server using whatever cache settings are appropriate for what you're trying to accomplish. I recommend selecting "Build cache manually after the service is published" and then, in ArcCatalog, right-click on the service and select Manage Cache > Manage Tiles to manually start the caching job with n number of caching server instances (which will be limited based on the maximum number of instances you have set in the System\Caching Tools service on your server). After that's done you can right-click on the service again and select Manage Cache > Export Cache and then chance the export cache type to TILE_PACKAGE. I recommend doing this on 10.2+ as this workflow in previous versions was error prone due to some bugs that appear to have now been fixed. While ArcMap *can* cache, it's really not optimized for it.
... View more
03-07-2014
10:50 AM
|
0
|
0
|
950
|
POST
|
Are you using the services as tiled layers or dynamic layers? Do you get the error regardless of extent or scale? Are manipulating the layer properties in any way in your code? A quick test below displayed both layers for me: mMapView = (MapView) findViewById(R.id.map); mMapView.addLayer( new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer")); mMapView.addLayer( new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Reference/MapServer"));
... View more
03-07-2014
07:57 AM
|
0
|
0
|
542
|
POST
|
You are right about the geometry. When I tested Graphic.toJson() it was with a graphic that had attributes, and so when I logged the JSON I got a wall of text and thought it was working, but looking closer it only listed the attributes and not the geometry. There are a few workarounds possible. Once is dumping the graphics into a FeatureSet and then using FeatureSet.toJson(). I have confirmed that doing so results in a JSON string that does contain geometry (albeit without the spatial reference). Alternatively, if all you really care about are geometries because you have no attributes, then you can use GeometryEngine.geometryToJson(). Can I ask what you intend to do with the JSON? If your purpose it to cache the graphics to local storage, you will find that your performance hit will be significant as the number of graphics grows large. An exponentially faster solution for local caching is something like this.
public static boolean writeCachedFeatureSet(FeatureSet featureSet, File cacheFile) {
cacheFile.getParentFile().mkdirs();
try {
FileOutputStream fos = new FileOutputStream(cacheFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
ObjectOutputStream output = new ObjectOutputStream(bos);
output.writeObject(featureSet);
output.close();
return true;
} catch (Exception e) {
// handle exception
}
return false;
}
public static FeatureSet readCachedFeatureSet(File cacheFile) {
try {
FileInputStream fis = new FileInputStream(cacheFile);
BufferedInputStream bis = new BufferedInputStream(fis);
ObjectInputStream input = new ObjectInputStream(bis);
FeatureSet featureSet = (FeatureSet) input.readObject();
input.close();
return featureSet;
} catch (Exception e) {
// handle exception
}
return null;
}
You can also make use of local geodatabases as of 10.2.0, but all of the related classes are in beta. I'm really looking forward to utilizing those in future apps, but I haven't yet had the inclination to rewrite anything involving local geodatabases so I can't comment on or suggest efficient workflows related to them.
... View more
03-05-2014
04:55 AM
|
0
|
0
|
609
|
POST
|
I'll take a stab at this, at least in part. Hopefully someone from ESRI can elaborate further. In the beta version of the SDK (and possibly even in the first few releases?) the Graphic object was mutable. It made a number of things far easier (i.e. manipulating symbology, attributes, etc) and in the other SDKs/APIs that I've worked with the Graphic object is still mutable. I'm sure the Android SDK team had very good reasons to make it immutable, or at least I hope so. Perhaps it was more of a purist decision rather than a practical one, but that is what we as developers are left with. Perhaps the non-final members and package level setters are remnants of it's original, mutable implementation, and now the immutability is ensured based on package level logic rather than being something enforce by the design itself. For example, if you call featureLayer.updateGraphic(graphicUid, myNewGeometry), my guess (based on the immutability claim) is that something like this is really taking place inside the updateGraphic method. Graphic oldGraphic = getGraphic(graphicUid);
Graphic newGraphic = new Graphic(myNewGeometry, oldGraphic.getSymbol(), oldGraphic.getAttributes());
privateGraphicsList.remove(oldGraphic);
privateGraphicsList.add(newGraphic); Therefore, behind the scenes the state of the object is never changing because none of the package level classes use the setters. This is, of course, just a guess and obviously means that there is dead code. I think that early on there may have been a conversation like this... SDK Developer: "Even though the Graphic object isn't immutable in any of our existing APIs, and wasn't immutable in our beta API, I think we should make it immutable now." Manager: "Why?" SDK Developer: "Well, otherwise in our SDK the layers need to be aware of changes to geometry, symbols, attributes, etc for all of the graphics they contain. This is Java so I don't have events and dependency objects to work with. It's really a pain and creates more overhead than I like. Wouldn't it be nice if I could do all of the work when a graphic is added and then never have to worry about it again?" Manager: "Wouldn't that be a departure from the design patterns employed by our other API/SDK teams?" SDK Developer: "Huh?" Manager: "And wouldn't that make life harder on the developers who utilize our SDK to leverage the rest of our product suite?" SDK Developer: "Who?" I jest a little here, but the beta SDK was more developer-friendly, as are ESRI's other APIs/SDKs imho. This isn't meant as an insult to the Android SDK team; they've done a fine job and the few members of their team who frequent this forum are both knowledgeable and helpful, and I hope they don't take this post in the wrong way. I don't doubt that they had very good reasons for departing from the standards used by the other teams, I just don't know what those reasons may be, and some things that are very easy in the other APIs (directly accessing a graphic object in a feature layer, manipulating the state of a graphic, etc) are much more tedious in the Android SDK. Regarding your question about the spatial reference... in some of the other APIs the graphic has a Geometry field, and the Geometry field has a SpatialReference field. So in Silverlight, for example (where the graphic happens to be mutable), if you want to set spatial reference for a graphic it's simply a matter of myGraphic.Geometry.SpatialReference = new SpatialReference(wkid). In Android, for some reason, it doesn't. The graphic's geometry is assumed to be in the same spatial reference as the layer you add it to. It's your responsibility as a developer to ensure that is the case or to reproject is as necessary before adding it to a layer. Why do you need the spatial reference of the graphic? Can you just get the spatial reference of the layer instead? I did a quick test and Graphic.toJson() does work as expected for me (using SDK 10.2.0) without overriding anything. Also, assuming you have multiple graphics you are wanting to convert to JSON, you may want to look at using FeatureSet.toJson() instead. Regarding your question about getUid() and getId()... I think that has to do with the immutability of the graphic. The graphic that you create manually, before you add it to a layer, isn't going to have a uid because it is logic inside of the GraphicsLayer class that generates the uid. What must be happening, then, is that when you call layer.addGraphic(myGraphic) it determines what the uid should be and then creates a copy of that graphic (with a new reference) using one of the package level constructors such as Graphic(int, Geometry, Symbol, Map<String,Object>). If I were a betting man, I'd bet that the first parameter in that constructor is the uid. Again, this is part of what makes the Android SDK more painful to work with. Let's say that you have a Graphic array in a FeatureSet returned by a query, and you add those graphics to a layer. The graphics in the layer are NOT the same as the graphics in your FeatureSet. If you want to have an array or list of the actual graphics in your layer, you have to do something like this: int[] uids = myLayer.getGraphicIDs();
Graphic[] layerGraphics = new Graphic[uids.length];
for (int i = 0, i < uids.length; i++) {
layerGraphics = myLayer.getGraphic(uid); // sometimes this is null even though you just got the uids
} But then again, since the graphics are immutable, it's of questionable use to maintain this array in your own class anyway, because any changes to the graphic will require the new graphic to be created in it's place. Also note with the code above, don't call this until you know that the Graphics have all been loaded in the feature layer. How do you know when that's happened, you ask? Good question. The documentation says that if you set an OnStatusChangedListener then you should see a Status.LAYER_LOADED in onStatusChanged(). If anyone ever sees that, let me know. I've never seen it work.
... View more
02-28-2014
11:58 AM
|
0
|
0
|
609
|
POST
|
If you're still wrestling with this issue and want someone else to test it out, feel free to PM me. I can give you my email address and if your able to email your code to me then I can replicate it on one of my devices and see if I can figure out what the problem might be.
... View more
02-26-2014
12:27 PM
|
0
|
0
|
862
|
POST
|
That's not an error that I've seen before. By chance, are you overriding onDestroy and not calling super.onDestroy() at the end of the method?
... View more
02-25-2014
11:54 AM
|
0
|
0
|
862
|
POST
|
Your question would probably be more relevant in the forum for ArcGIS App for Smartphones and Tablets, as this really has nothing to do with the SDK. At any rate, all you really have to do is exactly what the linked blog states: change "http://" to "arcgis://" in for webmap links on mobile websites, and when an Android or iOS user clicks on the link, assuming that they have the ArcGIS App installed on their phone or tablet, they will be able to open the webmap with the app rather than the mobile web browser. If you want to test this, open up this thread on your phone and click the following link to KY State Parks. Note that the arcgis:// prefix in that URL breaks the link on desktop browsers, but works for tablets if the ArcGIS App is installed. If you have any follow up questions about the ArcGIS App, I'd encourage you to post it in the forum I mentioned above. Best of luck.
... View more
02-25-2014
11:50 AM
|
0
|
0
|
218
|
POST
|
Dan, Thank you for following up on this, and I apologize that it's taken a couple weeks for me to respond. Here's some more information about the specifics of the map freeze problem that I've witnessed. I have witnessed this in versions 10.1.1 and in 10.2 of the ArcGIS Runtime SDK. It seems to be more likely to occur with touch-triggered panning and zooming rather than programmatic panning and zooming, but that may just be perception. I've witnessed it on 5 different Asus Tranformer Pad Infinity TF700Ts. It's the only tablet model that we are currently using for Android ArcGIS applications. As arunkoul also mentioned, event listeners still trigger while the mapView is frozen. For example, if I make the motion to pan the map and print out the new extent in the logs, I can see that the extent changes. Likewise, I can still tap a point on the mapView and see the coordinates being logged while the mapView is frozen. Once frozen, the mapView never unfreezes. The rest of the UI remains responsive. So far I've only done extensive testing with a mapView containing offline layers. That is, an ArcGISLocalTiledLayer initialized with a tpk stored on an SD card, plus several ArcGISFeatureLayers initialized with JSON layer definitions and FeatureSets. I don't have any specific code to share. I've never experienced the problem while the application has been in the middle of processing any custom code on the UI thread, and it has happened without any listeners set on the mapView. I will try testing some of the samples as well. The hardest part with isolating this problem is that it's incredibly intermittent and doesn't print any errors to the logs when it does freeze. As I mentioned in my first post, it's not repeatable; it may freeze at a certain extent one time, but then I can reload the app and programmatically go back to the same extent with no problem.
... View more
02-18-2014
08:39 AM
|
0
|
0
|
712
|
POST
|
Can someone from ESRI please comment? This looks like a long standing issue, first mentioned over a year ago in this thread: Dynamic layer does not load or only after device rotation Does this ever actually fire, and if so, what are the conditions? I have an issue where I'm trying to update the symbology for a few graphics after an ArcGISFeatureLayer has loaded, and if I try to do this on status INITIALIZED it sometimes crashes the program. Here are the relevant LogCat lines: 02-11 17:18:39.846: I/Runtime Core(5226): encoding image failure in Picture_marker_symbol::to_JSON 02-11 17:18:39.846: A/libc(5226): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 5310 (pool-2-thread-1) As it's intermittent, it seems obvious that calling Layer.updateGraphic() after STATUS.Initialized is error prone, but I can't find a reliable way to know that it is a safe call to make. Obviously I can put in an arbitrary delay which should *fix* the problem, but I have to believe there is a cleaner way to do this. Can someone from ESRI please enlighten me?
... View more
02-11-2014
01:25 PM
|
0
|
0
|
307
|
POST
|
You definitely don't need to convert anything to polygons to do this. If you are using an ArcGISFeatureLayer then what you want to do it set an OnSingleTapListener on your MapView, and then in your OnSingleTap() method call featureLayer.getGraphicIDs(x, y, tolerance) where the tolerance is a dp value. Increasing the tolerance will increase the radius around the tapped point for which graphic ids will be returned. In my experience 15 is a good value, but depending on the scale the map is at, higher or lower values may be appropriate. The results are sorted, however, so the id at index 0 will be the graphic closest to the tapped point. If you are getting an empty array returned then you need to increase your tolerance parameter. If you are using an ArcGISDynamicMapServiceLayer then the concept is similar: it's all about setting an appropriate tolerance around the point. In this case you'll be using an IdentifyTask to get a feature from the server, and so in your IdentifyParameters you'll want to call setTolerance(tolerance) before executing your IdentifyTask.
... View more
12-20-2013
05:49 AM
|
0
|
0
|
309
|
POST
|
In Android you can do this by changing the EditText to an AutoCompleteTextView in your xml layout, and then setting an adapter on it in your activity. Something similar to this (I'm typing the code directly into this window, so please forgive any syntax errors)...
String[] myAddresses = new String[] { ... };
ArrayAdapter<String> addressAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, myAddresses);
AutoCompleteTextView addressTextView = (AutoCompleteTextView) findViewById(R.id.addressText);
addressTextView.setAdapter(addressAdapter);
In reality you probably want to read your array of addresses from a file or other external source rather than hard code them, but you get the idea.
... View more
12-20-2013
05:28 AM
|
0
|
0
|
314
|
POST
|
Recently we began doing online editing of data by enabling Feature Access on some services, but we are having issues where features are being duplicated because there is no rollback when a failure occurs, and on subsequent attempts features that have been previously created are created again with different object ids. When I look at the service properties I can see that "Supports Rollback On Failure" is false, but I don't see anywhere in server manager where I can enable this. How can I configure my service to support rollback? edit: fixed title " from conversion from old forums to geonet (to make it wasier to read) -ras
... View more
12-19-2013
12:38 PM
|
0
|
9
|
5151
|
POST
|
On your MapView you can set an OnSingleTapListener, and then in your listener's onSingleTap() method iterate through your layers and call getGraphicIDs() with the x and y from the tap plus whatever tolerance is appropriate (I recommend starting with a tolerance of 15 and adjusting as necessary). That is assuming that your layers are of type GraphicsLayer or ArcGISFeatureLayer. If you are using the new FeatureLayer class (just introduced in 10.2) then getFeatureIDs() is the equivalent method to use.
... View more
12-11-2013
04:56 AM
|
0
|
0
|
198
|
POST
|
I don't believe anything like that is currently baked into the API, but the building blocks for it are certainly in place. There is an isVisible() method that you can use to know when a layer is visible, but I haven't done much testing to know if this value updates automatically based on MapView scale changes or if it only updates based on programmatic changes. You'd have to test to see what gets returned with a layer is set to visible but outside of its scale range. That said, I doubt that it considers the extent at all (but I could be wrong). For that, you have a couple methods you can use. For an ArcGISDynamicMapServiceLayer, you'll want to look at getMapServiceInfo(). The MapServiceInfo object contains information about the extent of the service as well as the min and max scale at which it is visible. For an ArcGISFeatureLayer the corresponding method is getLayerServiceInfo(), which returns a LayerServiceInfo object with similar properties. On your MapView you can then set pan and zoom listeners to iterate through your layers to see which ones are visible using a combination of isVisible() and the properties from your MapServiceInfo/LayerServiceInfo objects.
... View more
12-09-2013
05:05 AM
|
0
|
0
|
210
|
POST
|
I've trying to diagnose an intermittent problem and I'm hoping that someone can help me out. I developed an app that is being used for offline data collection, and occasionally it freezes during panning or zooming. When I say freezes, I mean that the tiles from an ArcGISLocalTiledLayer partially load and then the MapView becomes unresponsive and ceases to load any more tiles. I've witnessed this across a variety of different tpk files used for the tiled layer. Looking in LogCat, there are no errors being logged and gestures still trigger ArcGIS.Gesture entries. I wrote some code to zoom the map to different points every few seconds, and even when the map view freezes I still see my LogCat entries zooming to different locations on the MapView... getCenter() correctly returns the new zoom point and getScale() returns the new scale, even though the MapView tiles don't change. The rest of the UI normally remains responsive (for example, tapping a button will still open a DialogFragment) although sometimes tapping a button while the MapView is frozen will result in a dialog stating that the application has stopped responding. I can only assume that an error is being thrown in a background thread as it is processing the bitmaps for the tiles, but it seems completely random. For example, after randomly generating 100 points and scales on the first run I put those into an array so that now the first 100 pan/zoom iterations are always the same so that I can have some consistency between tests. Sometimes it freezes after a dozen or so iterations, other times it can go well into the hundreds before finally freezing, leading me to believe it's not a problem with the tpk file itself because the error never consistently occurs in any one place. Any ideas how I can go about debugging this, or at the very least programmatically detect when the MapView becoming unresponsive so that I can reload it without users having to close out and reload the application?
... View more
12-05-2013
12:27 PM
|
0
|
8
|
3037
|
Online Status |
Offline
|
Date Last Visited |
11-11-2020
02:23 AM
|