POST
|
Thanks Derek. I agree. In hindsight, I guess my question was more of "What are the typical ways of accessing third party HTTP APIs and providing that data through RESTful applications/APIs?". Not really related to ESRI's API at all. 🙂
... View more
11-18-2011
07:47 AM
|
0
|
0
|
313
|
POST
|
I have gone back and forth on how to provide spatial data from ArcGIS Server in an MVC application and would like some suggestions on how to best architect this solution. Assume a hypothetical Pipelines controller with typical CRUD style actions (Index, Details, Create, Edit). The Model for Pipelines is split between Entity Framework and ArcGIS Server. A request to the Details action would require querying EF and querying ArcGIS Server. The response could be either HTML or JSON depending on HTTP Header Accept. The question is... what's the best solution for where that ArcGIS Server query should occur and what should be provided in the controller's response? A couple options I've considered Provide all details (both spatial and non-spatial) for the Pipeline. Now my HTTP API is decoupled from ESRI, and I can construct my own Pipeline object where the underlying model(s) is abstracted for the consumer (I like). But there's a lot of work here. I have to myself make a web request from the controller and deserialize ArcGIS Server's JSON. That deserializing that can get a little tricky with more complex geometry types. Provide all EF model data (non-spatial) along with data describing the ArcGIS Server query (url, where clause, out fields, etc...). This is easy, but the consumer/client is aware of the AGS model, has to themselves make that query, and has to include logic on how to combine the GIS results to the previous returned data.
... View more
11-18-2011
06:31 AM
|
0
|
2
|
1241
|
POST
|
By default, map services return a maximum of 1000 features. This configuration can be changed from the Parameters tab of the Map Service Properties in either ArcCatalog or ArcGIS Server Manager.
... View more
10-19-2011
10:00 AM
|
0
|
0
|
199
|
POST
|
Good work! Glad you got what you needed Ben. My take on MVVM really comes down to responsibility and separation of concerns. The view is about receiving input and setting how to display information (map click, formatting and displaying the coordinates, etc...). The view model is about retrieving data from the model or view, performing some presentation logic (publishing the coordinates via Messenger or whatever else you would like to do with them), and being able to test that logic. The Action in this case is just a tool to better wire those two together. Because its an Action, there's also the added benefit of being reusable and blendable. In my opinion, lots of MVVM newbies get caught up with the no code behind nonsense. In this case, you could have just as easily added a handler for the Map control's MouseMove event and set the property on the View Model in the code behind directly. You would still have the same separation of concerns and still just as testable. Either way, the coordinate transformation logic and wiring to the view model is handled by the view. Without the use of an Action, you would have sacrificed the reuse and blendability, but maybe that's not a big deal for your situation. ... just my .02
... View more
10-17-2011
06:23 AM
|
0
|
0
|
172
|
POST
|
Darina makes a good point. This situation is better suited for a TriggerAction than a behavior. A nice solution would be an action to update a property on another object when invoked. Luckily, Microsoft already did this for us with the ChangePropertyAction in the Blend SDK. Using ChangePropertyAction, you can bind to TextBlock.Text or a property on your View Model - whatever you like. We do need to extend it and do 1 small override for our coordinate calculation. It ends up looking like... using System.Windows;
using System.Windows.Input;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Geometry;
using ESRI.ArcGIS.Client.Projection;
using Microsoft.Expression.Interactivity.Core;
public class CoordinateChangePropertyAction : ChangePropertyAction
{
protected override void Invoke(object parameter)
{
this.Value = GetCoordinateString(parameter as MouseEventArgs);
base.Invoke(parameter);
}
private string GetCoordinateString(MouseEventArgs e)
{
string mouseCoordString = string.Empty;
Map map = AssociatedObject as Map;
Point mouseLoc = e.GetPosition(map);
MapPoint coordLoc = map.ScreenToMap(mouseLoc);
if (coordLoc != null)
{
WebMercator webMercator = new WebMercator();
MapPoint latLon = webMercator.ToGeographic(coordLoc) as MapPoint;
mouseCoordString = string.Format("Lon {0:F4}° Lat {1:F4}°", latLon.X, latLon.Y);
}
return mouseCoordString;
}
} and the XAML... (this is assuming you have a LayoutRoot bound to your view model) <esri:Map x:Name="map_BaseMap">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseMove">
<MyActionNamespace:CoordinateChangePropertyAction TargetObject="{Binding DataContext, ElementName=LayoutRoot}" PropertyName="SomePropertyOnTheViewModelToBindTo"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</esri:Map> That's it - now you have it in your view model. Expose it in whatever view model is supporting your TextBlock. Of course if ChangePropertyAction is not available for your project or you can't use the Blend SDK for any reason, you could still use Darina's action from above. You would just need change the Type from TextBlock to whatever fits for you (your View Model perhaps or some abstraction of it). Instead of updating the .Text property, you would update the needed property on that object. One suggestion. You may want to consider eliminating the formatting to string from the action. Just return a MapPoint. Leave it up to the TextBlock displaying the data to decide how it should be formatted. Its really simple to do so using Binding's StringFormat property or IValueConverter.
... View more
10-13-2011
01:38 PM
|
0
|
0
|
1268
|
POST
|
Are the Map and coordinate TextBox in the same View or in 2 different Views? Knowing only about these 2 controls and no other features of your application, I would have them in the same view. This is simply because the TextBox involves no additional presentation logic, model data, or unique feature set. Its just an additional control displaying the same data as your map but in a different way. So lets tackle that option (both in the same view). Essentially, your TextBox would like to display some information from another control in the UI. This is no different than if it wanted to display the Width of the map. No need to have the View Model intervene there - just bind one control to the other. The only problem is mouse coordinates are not publicly exposed like Width. We need to find some way to expose those from the Map. A Behavior is a valid option. You could create a Behavior with a property (or properties) to describe mouse coordinates and bind your TextBox to that property. If they are in different Views, the idea could still be the same. Now, you just need some way of communicating the mouse coordinates between Views (View Models). You could TwoWay bind the coordinates to your View Model that is updating some underlying model. Implement some decoupled way of sharing that model like Messenger/Event Aggregator or a common Service. Expose as a property on the second View Model and bind your TextBox to that.
... View more
10-13-2011
08:36 AM
|
0
|
0
|
1268
|
POST
|
It seems that the visibility of your radio button is really just about UI, not the underlying model. 2 options taking that perspective... Create Visual States to represent different visual representations of your interface (RadioButton visible or not) and change the state based on whatever logic applies. This could be done with in XAML with a DataStateBehavior. If its only the visibility of a single control you're concerned about, that could be overkill. Alternatively, you could bind the visibility to whatever value is determining it and build an IValueConverter to return Visible or Collapsed based on that value.
... View more
10-05-2011
10:19 AM
|
0
|
0
|
560
|
POST
|
How are the Layers created? Can you just set Visible = false (or xaml <Layer Visible=false />) at that time?
... View more
09-29-2011
10:25 AM
|
0
|
0
|
300
|
POST
|
You can control compatibility mode from IIS or via html headers
... View more
09-15-2011
06:27 AM
|
0
|
0
|
304
|
POST
|
Quick and untested, but something like... findTask.ExecuteCompleted += OnExecuteCompleted;
private void OnExecuteCompleted(object sender, FindEventArgs e)
{
Geometry zoomGeometry;
foreach (var result in e.FindResults)
{
if (zoomGeometry == null)
{
zoomGeometry = result.Feature.Geometry.Extent;
continue;
}
zoomGeometry = zoomGeometry.Extent.Union(result.Feature.Geometry.Extent);
}
YourMap.Extent = zoomGeometry;
}
YourMap is a reference to your map control
... View more
07-21-2011
11:42 AM
|
0
|
0
|
189
|
POST
|
Can you give any examples or point me in the right direction for... using "an attached property that takes care of handling binding" Attached Property...
public static class MapExtentHelper
{
public static readonly DependencyProperty MapZoomGeometryProperty = DependencyProperty.RegisterAttached("MapZoomGeometry", typeof(Geometry), typeof(MapExtentHelper), new PropertyMetadata(new PropertyChangedCallback(OnMapZoomGeometryChanged)));
public static Geometry GetMapZoomGeometry(DependencyObject d)
{
return (Geometry)d.GetValue(MapZoomGeometryProperty);
}
public static void SetMapZoomGeometry(DependencyObject d, Geometry value)
{
d.SetValue(MapZoomGeometryProperty, value);
}
private static void OnMapZoomGeometryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Map map = d as Map;
if (map == null) throw new ArgumentException("DependencyObject must be of type ESRI.ArcGIS.Client.Map");
Geometry newZoomGeometry = GetMapZoomGeometry(map);
if (map.Extent == null)
{
map.Extent = newZoomGeometry.Extent;
}
else
{
map.ZoomTo(newZoomGeometry);
}
}
}
Use with Map control...
<esri:Map Extensions:MapExtentHelper.MapZoomGeometry="{Binding SomeGeometryOnViewModel}"/>
Where "Extensions" is the mapped namespace for your static class.
... View more
05-17-2011
07:30 AM
|
0
|
0
|
422
|
POST
|
I am having a difficult time mocking ESRI.ArcGIS.Client.LayerInfo (and ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer) because these class are sealed, implement no interfaces, and have private property setters. I've experimented some with Duck Typing and other adapter like patterns but keep coming up with dead ends. Any suggestions or experience dealing with this issue? I should also add I am working primarily with MOQ as a mocking framework now but will be taking a look at TypeMock specifically for this issue.
... View more
04-22-2011
12:21 PM
|
0
|
0
|
533
|
POST
|
Agree with Jennifer. Expose properties like Layers from your view model (not UI elements like a map control) and bind to those. One workaround for properties like Map.Extent that will not support binding is attached properties. Create an attached property (maybe BindableExtent) and bind that to your view model. In the callback for the property change, do some work to set the actual map extent. Quick and dirty example:
public static readonly DependencyProperty BindableExtentProperty = DependencyProperty.RegisterAttached("BindableExtent", typeof(Geometry), typeof(OwnerClass), new PropertyMetadata(new PropertyChangedCallback(OnBindableExtentChanged)));
public static Geometry GetBindableExtent(DependencyObject d)
{
return (Geometry)d.GetValue(BindableExtentProperty);
}
public static void SetBindableExtent(DependencyObject d, Geometry value)
{
d.SetValue(BindableExtentProperty, value);
}
private static void OnBindableExtentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Map map = d as Map;
var newExtent = (Geometry)e.NewValue;
map.ZoomTo(newExtent);
}
... View more
01-05-2011
06:28 AM
|
0
|
0
|
367
|
POST
|
Just updated updated to v2.0 and encountering exception when trying to set the spatial reference and extent on map with layers set via data binding. Any suggestions? Exception... {System.Windows.Markup.XamlParseException: Set property 'ESRI.ArcGIS.Client.Map.Extent' threw an exception. [Line: 89 Position: 85] ---> System.NullReferenceException: Object reference not set to an instance of an object. at ESRI.ArcGIS.Client.Map.getSpatialReferenceFromLayers() at ESRI.ArcGIS.Client.Map.get_SpatialReference() at ESRI.ArcGIS.Client.Map.set_Extent(Envelope value) --- End of inner exception stack trace --- at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator) at LJA.Client.RCP.QBMapFull.MapModule.MapView.InitializeComponent() at LJA.Client.RCP.QBMapFull.MapModule.MapView..ctor()}
<esri:Envelope x:Key="InitialExtent" XMax="-10539988" XMin="-10681703" YMax="3541573" YMin="3405056">
<esri:Envelope.SpatialReference>
<esri:SpatialReference WKID="102113"/>
</esri:Envelope.SpatialReference>
</esri:Envelope>
<esri:Map x:Name="TheMap" Layers="{Binding Layers, Mode=OneWay}" Extent="{StaticResource InitialExtent}">
</esri:Map>
On view model...
public LayerCollection Layers
{
get { return _layers ?? (_layers = new LayerCollection()); }
set
{
if (value == _layers) return;
_layers = value;
OnPropertyChanged("Layers");
}
}
... View more
05-03-2010
09:30 AM
|
0
|
1
|
406
|
Online Status |
Offline
|
Date Last Visited |
09-09-2021
02:52 PM
|