POST
|
After more debugging, I figured it out! The json for Color_ramp function on the page Add raster data—ArcGIS Runtime SDK for .NET | ArcGIS for Developers is incorrect. It has 2 extraneous commas. In the json below, the extra commas were at the end of lines 23 and 24. Michael Branscomb, someone should correct this on the developers site. Follow-up question for anyone who is reading this. Is there a syntax spec for the color ramp raster function? I would like to be able to use either actual values or % values to set my colors. This sample doesn't have either of those parameters. But other pages indicate maybe there is a way to do that. See: Color ramp objects—Common Data Types | ArcGIS for Developers {
"raster_function":{"type":"Color_ramp_function"},
"raster_function_arguments":
{
"resizable":{"bool":false,"type":"Raster_function_variable"},
"color_ramp":
{
"color_ramp":
{
"ramps":
[
{"to_color":[0,255,0],"from_color":[0,191,191],"num_colors":3932,"type":"Algorithmic_color_ramp","algorithmic_type":"hsv"},
{"to_color":[255,255,0],"from_color":[0,255,0],"num_colors":3932,"type":"Algorithmic_color_ramp","algorithmic_type":"hsv"},
{"to_color":[255,127,0],"from_color":[255,255,0],"num_colors":3932,"type":"Algorithmic_color_ramp","algorithmic_type":"hsv"},
{"to_color":[191,127,63],"from_color":[255,127,0],"num_colors":3932,"type":"Algorithmic_color_ramp","algorithmic_type":"hsv"},
{"to_color":[20,20,20],"from_color":[191,127,63],"num_colors":3935,"type":"Algorithmic_color_ramp","algorithmic_type":"hsv"}
],
"type":"Multipart_color_ramp"
},
"type":"Raster_function_variable"
},
"raster":{"name":"raster","is_raster":true,"type":"Raster_function_variable"},
"type":"Raster_function_arguments"
},
"type":"Raster_function_template"
}
... View more
08-16-2019
10:47 AM
|
1
|
2
|
908
|
POST
|
I'm trying to implement a raster function, starting with the code in the Raster Layer Raster Function sample. The sample uses Hillshade. I can get that to work, but I'm getting an exception with the Color_ramp function. I have not investigated this with v100.5, but I did check the release notes and don't see anything related. I'm using the json for Color_ramp function listed on Add raster data—ArcGIS Runtime SDK for .NET | ArcGIS for Developers . I'm getting an exception in the RasterFunction.FromJson() method. The exception is "invalid start of field name - expecting \"": } : 1158 If I add some random spaces in the json string, the 1158 number in the exception changes, so I'm thinking that is possibly the location in the string where the problem is. Stack trace is: at Esri.ArcGISRuntime.ArcGISException.HandleCoreError(CoreError error, Boolean throwException) at RuntimeCoreNet.GeneratedWrappers.Interop.CheckError(IntPtr errorHandle, Boolean throwOnFailure, GCHandle wrapperHandle) at RuntimeCoreNet.GeneratedWrappers.CoreRasterFunction.FromJSON(String jSON) at Esri.ArcGISRuntime.Rasters.RasterFunction.FromJson(String json) Here is my code. I added a line to parse the json to make sure it was valid json syntax, and that works OK. string colorRamp =
@"{
""raster_function"":{""type"":""Color_ramp_function""},
""raster_function_arguments"":
{
""resizable"":{""bool"":false,""type"":""Raster_function_variable""},
""color_ramp"":
{
""color_ramp"":
{
""ramps"":
[
{""to_color"":[0,255,0],""from_color"":[0,191,191],""num_colors"":3932,""type"":""Algorithmic_color_ramp"",""algorithmic_type"":""hsv""},
{""to_color"":[255,255,0],""from_color"":[0,255,0],""num_colors"":3932,""type"":""Algorithmic_color_ramp"",""algorithmic_type"":""hsv""},
{""to_color"":[255,127,0],""from_color"":[255,255,0],""num_colors"":3932,""type"":""Algorithmic_color_ramp"",""algorithmic_type"":""hsv""},
{""to_color"":[191,127,63],""from_color"":[255,127,0],""num_colors"":3932,""type"":""Algorithmic_color_ramp"",""algorithmic_type"":""hsv""},
{""to_color"":[20,20,20],""from_color"":[191,127,63],""num_colors"":3935,""type"":""Algorithmic_color_ramp"",""algorithmic_type"":""hsv""}
],
""type"":""Multipart_color_ramp""
},
""type"":""Raster_function_variable""
},
""raster"":{""name"":""raster"",""is_raster"":true,""type"":""Raster_function_variable""},
""type"":""Raster_function_arguments"",
},
""type"":""Raster_function_template"",
}";
var json = colorRamp;
try
{
JObject rss = JObject.Parse(json);
RasterFunction myRasterFunction = RasterFunction.FromJson(json);
}
catch (Exception e)
{
Console.WriteLine(e);
}
... View more
08-16-2019
08:36 AM
|
0
|
3
|
1001
|
POST
|
Quick bit of additional info. I tried this using LocalServer as it is done in the Dynamic Workspace Raster from the SDK Samples App, and I get similar behavior. The local server holds a reference to the raster even when a new/different raster file is chosen.
... View more
08-05-2019
11:37 AM
|
0
|
0
|
696
|
POST
|
Here is what I would like to do: Create a raster layer from a file Add the layer to the map var rlayer = new RasterLayer(new Raster("C:/...../myraster.tif"); Regenerate the raster (same filename if possible, but I have some flexibility) Refresh the raster layer with the newly updated raster file (so that the map is updated) My problem is that the raster file is still in use (presumably a reference held by the layer). So I can't delete the file or rename it. I tried a few things to try to uncouple the raster from the layer, but no luck. For example ... var layers = mapVm.Map.OperationalLayers;
var raster = myRasterLayer.Raster;
layers.Remove(layer);
raster = null;
layer = null;
System.GC.Collect(); I even tried to force garbage collection. I think that may have worked once or twice, but I can't replicate it reliably. I also tried the local server approach in the ArcGISRuntime.WPF.Samples.DynamicWorkspaceRaster sample, but same result. Any advice? Maybe I need to take a different approach?
... View more
08-02-2019
10:30 AM
|
0
|
2
|
875
|
POST
|
First, a general question about future versions of the runtime: Are there any plans to enhance the raster renderers or add a classify renderer? More generally, I'm doing some raster analysis and adding them to the map by creating a RasterLayer with the file path: var rlayer = new RasterLayer(path);
rlayer.Id = id;
rlayer.Renderer = RendererFactory.GenerateRenderer(product, path);
rlayer.Opacity = 0.6;
rlayer.IsVisible = false;
layers.Add(rlayer); RendererFactory is a class I wrote that chooses the renderer properties based on the type of file. The problem I'm running into is that even when I set the renderer properties to match the symbology in Pro, often times it doesn't render or has a very narrow range of colors. Anecdotally, this seems more likely to happen when the raster values are small (<1), or have a small range, or a small number of unique values. But I haven't really tried to narrow it down. This is an example of one my rasters in Pro: Here is it's corresponding symbology: The same raster rendered on my map looks like this: Here are the rendering parameters: IEnumerable<double> myGammaValues = new List<double>() { 1.0 };
var std = new StandardDeviationStretchParameters(2.0);
var numColors = Math.Ceiling(max - min);
if (numColors < 16)
numColors = 16;
ColorRamp myColorRamp = ColorRamp.Create(PresetColorRampType.Elevation, (uint)numColors);
var rendrr = new StretchRenderer(std, myGammaValues, true, myColorRamp);
return rendrr; The result is the same if I change color ramp to DemScreen or if I use Min/Max parameters for the stretch renderer. However, if I set the layer renderer to null, I actually get a better rendering (albeit grayscale): Any advice on how to improve my raster rendering???? P.S. Sample raster attached.
... View more
07-16-2019
09:01 AM
|
1
|
0
|
485
|
POST
|
Nothing jumps out at me right away. I'll just offer some general debugging advice. You have a lot going on in the Initialize method. Consider breaking that up into separate methods. For debugging, try commenting out some stuff until you get your map responding the way you want. Then when you know which lines are causing the problem, you can make adjustments or corrections.
... View more
04-19-2019
08:00 AM
|
0
|
1
|
1375
|
POST
|
Yes, still working for me in 100.4. Sounds like you might have something else causing your problem.
... View more
04-05-2019
03:57 AM
|
0
|
0
|
489
|
POST
|
Thanks for the link. But it looks like the 10.2.7 version has a Thumb class to support the swipe operation. Unless I'm missing it, the 100.x runtime doesn't have a Thumb class.
... View more
03-29-2019
11:54 AM
|
0
|
1
|
1006
|
POST
|
Many of the ESRI demos have this as a feature. You have a handle that you can drag across the map (left-right). As you "swipe" from one side to the other, the top layer is "peeled back" to reveal the layer under it. If you stop in the middle, you'll essentially have a split screen showing 2 layers.
... View more
03-29-2019
08:32 AM
|
0
|
3
|
1006
|
POST
|
Has anyone implemented the classic layer swipe feature in a WPF application? Looking for example code or ideas on how to implement it.
... View more
03-28-2019
09:01 AM
|
0
|
5
|
1112
|
POST
|
We are doing that in our applications. See my responses in this thread: https://community.esri.com/thread/209862-how-to-use-elevation-data-in-a-mapview
... View more
03-27-2019
08:38 PM
|
0
|
3
|
1375
|
POST
|
I don't know about the performance issues in your specific case. For me, responsiveness is not an issue. There is no delay in tracking and displaying the mouse location in a status bar. However, my elevation source is built from local DTED files. So there is no possibility of a round-trip server hit. My educated guess is that you will not incur a round-trip to the server every time you query the elevation of a surface. That seems like a very inefficient implementation. I suspect that the surface could have incremental snapshot or cache of elevation data. My intuition says that if it operates this way, the cached/snapshot area of elevation data would match that of an associated SceneView. These are total guesses on my part. Maybe Michael Branscomb could weigh in? If that is the case, then you could try attaching that baseSurface to a behind-the-scenes SceneView (as show in code line 12, previous reply) and then syncing the SceneView's viewpoint to match that of your map view. There is some sample code for syncing map & scene displays in ESRI samples & docs, but here is what I have in my code as an example: private void OnViewpointChanged(object sender, EventArgs e)
{
if (!TheSceneView.IsVisible)
return; // don't sync when it's hidden; to improve performance
// Get the MapView or SceneView that sent the event
GeoView sendingView = sender as GeoView;
// Only take action if this geoview is the one that the user is navigating.
// Viewpoint changed events are fired when SetViewpoint is called; This check prevents a feedback loop
if (sendingView.IsNavigating)
{
// If the MapView sent the event, update the SceneView's viewpoint
if (sender is MapView)
{
// Get the viewpoint
Viewpoint updateViewpoint = TheMapView.GetCurrentViewpoint(ViewpointType.CenterAndScale);
// Set the viewpoint
TheSceneView.SetViewpoint(updateViewpoint);
}
else // Else, update the MapView's viewpoint
{
// Get the viewpoint
Viewpoint updateViewpoint = TheSceneView.GetCurrentViewpoint(ViewpointType.CenterAndScale);
// Set the viewpoint
TheMapView.SetViewpoint(updateViewpoint);
}
}
}
... View more
01-18-2019
08:48 AM
|
1
|
1
|
2021
|
POST
|
I think you can still probably make the detached elevation source work. Here is some of my basic setup code for a scene view that uses the world 3D map on the arcgis.com server. private readonly Uri _elevationUri = new Uri("http://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer");
private void SetupSceneElevation()
{
// Add the elevation surface.
ArcGISTiledElevationSource tiledElevationSource = new ArcGISTiledElevationSource(_elevationUri);
Surface baseSurface = new Surface
{
ElevationSources = { tiledElevationSource }
};
TheSceneView.Scene.BaseSurface = baseSurface;
} You could do this same thing in your code, but then skip line 12 because you're not attaching it to a view. Obviously you will need to change the scope of my baseSurface variable, but you could then simply query the elevation at a map point using that: var elevation = await baseSurface.GetElevationAsync(point); You'll have to work out the specifics of the map view, etc. but here is some code that shows how you could work this into the mouse move event handler: var e = param as MouseEventArgs;
if (e == null)
return null;
var screenpoint = e.GetPosition(mapViewModel.MapView);
var mappoint = mapViewModel.MapView.ScreenToLocation(screenpoint);
if (mappoint == null)
return null;
if (mapViewModel.MapView.WrapAroundMode == WrapAroundMode.EnabledWhenSupported)
mappoint = GeometryEngine.NormalizeCentralMeridian(mappoint) as MapPoint;
var elevation = await baseSurface.GetElevationAsync(mappoint);
... View more
01-18-2019
08:04 AM
|
0
|
3
|
2021
|
POST
|
I realize this is an old question, but thought I would reply in case anyone is still looking for a solution or additional examples. You noted that, "... it is only possible to use the elevation data when it is bound to a surface on a SceneView ..." However, SceneView is just a class. It's not required to be bound to a map. So think of it as a tool that you can use to manage data. It's only visible to the user when bound to a map, but still valid and fully-functional behind the scenes! (Pun intended). Mike provided a solution that uses a gpk, but that adds some complexity to the solution. Here are some code snippets that are consistent with your original ideas: public Surface Dted1Surface { get; private set; }
public SceneView SceneView1 { get; private set; }
Dted1Surface = new Surface();
SceneView1 = new SceneView();
// Create a raster elevation source based on all files in dted1Files
RasterElevationSource dted1ElevSource = new RasterElevationSource(Dted1Files);
await dted1ElevSource.LoadAsync();
dted1ElevSource.Name = "DTED1";
// Create a Surface based on the elevation source
Dted1Surface.ElevationSources.Add(dted1ElevSource);
Dted1Surface.Name = "DTED1 Surface";
await Dted1Surface.LoadAsync();
// Create a Scene and assign the created surface to its BaseSurface
Scene dted1Scene = new Scene();
dted1Scene.BaseSurface = Dted1Surface;
await dted1Scene.LoadAsync();
// Create a SceneView and assign created scene to its Scene
SceneView1.Scene = dted1Scene;
MapPoint point;
// point = GetDesiredElevationLocation();
double result = await Dted1Surface.GetElevationAsync(point);
... View more
10-16-2018
09:10 AM
|
0
|
3
|
2021
|
Title | Kudos | Posted |
---|---|---|
1 | 07-16-2019 09:01 AM | |
1 | 08-16-2019 10:47 AM | |
1 | 01-18-2019 08:48 AM | |
1 | 01-10-2017 10:29 AM | |
1 | 10-28-2014 08:02 AM |
Online Status |
Offline
|
Date Last Visited |
11-11-2020
02:23 AM
|