DOC
|
Within the directive to "build a better system for tracking best management practice implementations on farms in VT," we saw an opportunity to shatter expectations for how to use the ArcGIS tools we were familiar with. This presentation will explore some outside-the-box approaches to building an enterprise web application based on ESRI’s web and server tools. In past developer summits we have seen repeated recommendations to "not use the ArcGIS JS API inside of an AngularJS application for big, enterprise applications." So, we did anyway. We’ll discuss the structure of the application that wraps AngularJS inside of Dojo “Require” statements, and how we feel that the benefit is worth the pain. In past developer summits we have heard discussions of folks struggling with a need for record-level security in presenting ArcGIS Server feature service content. We encountered a similar need for this recent farm BMP project. Farm data is highly confidential such that very few people have sweeping access to view all of it. Our system needed to provide an interface for individuals with less-than-full-access to work with spatial data associated with specific farms. Based on a user’s Vermont-state farm-project associations (which projects they manage), they would be allowed to see the spatial records for only "their" farms - and no others. At first we planned to use ArcGIS Server for the application, but as these security needs developed, we switched gears. We will discuss how we rolled our own system using NodeJS and SDE, on top of a PostGIS database, to serve up the feature class data with record level security capability, and without using ArcGIS Server. Yes! Feeding an ArcGIS JS API-based mapping tool from NodeJS, not ArcGIS Server. However, the data was maintained in standard feature-class format so that users with ArcGIS Desktop could still connect to, and manipulate, the data like with any other enterprise ArcSDE database. We will look at the high level structure of the solution to just show what is possible, and then dig into some implementation details in JS and PGSQL code.
... View more
01-08-2016
01:25 PM
|
7
|
0
|
2191
|
POST
|
I am not looking for a step-by-step (unless you are so inclined to write-it)... but rather a big-picture view of this setup. We have three a web app (client) running on the browser that will be making requests against both a NodeJS-based REST service, and ArcGIS Server 10.3.1 (or whatever is newest). Because ArcGIS JS API and ArcGIS Server already have a great OAuth2-based authentication system in place, I want the NodeJS service to tie into that same OAuth setup controlled by ArcGIS Server such that if a user authenticates against ArcGIS Server, they can also access the content of the NodeJS service. If they are not authenticated against ArcGIS, then they cannot use the NodeJS service. I am unclear if ArcGIS and Node need to share some back-end database table of token data, or if I can have the NodeJS service forward the token stuff it gets from the client to ArcGIS Server for checking? Is it possible to have the client hit the NodeJS service first, and then get redirected to the ArcGIS login prompt if they are not logged in? Thanks for any thoughts! Nick
... View more
05-29-2015
12:43 PM
|
0
|
0
|
3261
|
POST
|
Hi folks! We want to store configurable data for our web application in some flat database tables. Write now we will insert/update these from the back-end. But eventually the users will be able to edit the configuration data in these tables, so they will be read/write. In other words eventually this read only configuration data will turn into a basic sort of CMS. We are divided here between publishing the postgresql table via SDE as a table in a map service, or using custom web services. It appears however that you cannot simply create an MXD, put just one table in it (no feature classes, or other map data) and publish it as a map service. So in order to use the ArcGIS Rest API to manage my table I would need at least a dummy feature class in the map service. Any time that I need to put a dummy in place to make something work raises a red flag that I am probably not using the best solution. The other solution is a custom web service. The down side is that using a custom web service basically means splitting up our configuration tables away from the rest of our data which is all managed in the geodatabase. It would be nice to have everything in one place. In short - how do other people handle this sort of situation with their JS API web apps? Our JS API app uses AngularJS, so it is not primarily Dojo oriented... if that matters. Thanks for the input! Nick
... View more
04-17-2014
01:22 PM
|
0
|
1
|
410
|
POST
|
Dear ESRI, I think there are people who would appreciate the option of using the editor widget without using the infowindow. The whole "hide() it after the click event fires" thing is a poor solution... yes it works, but it is a wasteful approach. It would be like me ordering a happy meal when I don't want the free toy. Instead of always getting the toy and tossing it out, can I just get the meal without the toy? I understand that the editor is a widget, and so it is a package-deal... and so I get why it is the way it is. I'm just suggesting that an extra config option to totally disable the infowindow functionality would be nice.
... View more
12-06-2012
09:20 AM
|
0
|
0
|
367
|
POST
|
Hi again! So, the answer to your initial query is "yes" - using the SDK explicit save sample to draw and then cut a polygon works fine. Unfortunately, I need my cutting workflow to be controlled via the codebehind, and not by the pre-packaged cut tool from the Editor widget..? The user needs to draw the cutting line and have it displayed on the map without having the cut happen yet - then after the user has checked some things, the user hits a button to finalize the cut, and that is when I am trying to get the cut to happen but getting the odd results. So I modified the Utilities->Cut SDK sample to my geometry service as well, and that also works. What I notice is that when the cut is submitted it submits all polygons on the map as possible cut targets, and then the returned results list of graphics contains all of those same polygons plus some extras if the cut cut anything. Yet the CutIndexes member of the CutEventArgs 'e' object passed to the CutCompleted event handler does not clearly define anything ... it has one index entry for each of the returned graphics, but each index entry's value is simply the number of index ... index [10] has a value of 10. How would one determine from the returned set of polygon graphics which polygon is the newly created cut, and which one it came from? Thanks for continuing to pay attention to this thread! Nick
... View more
09-22-2011
12:13 PM
|
0
|
0
|
541
|
POST
|
Quick follow up... I downloaded the SDK examples and tried to build them after having modified the geometry service URL in the Explicit Save sample, but get an error at runtime about some Init parameter XML file missing from inside the App.xaml.cs ...
... View more
09-21-2011
10:48 PM
|
0
|
0
|
541
|
POST
|
Hi Jennifer, I started thinking about what you were proposing but have taken a slight tangent. The reason is that even if using the editor's built-in command to cut worked, the work flow it requires is not quite what I want ... it is too much of a package deal, and I need a more customized work flow. I mean, I'll go that route if I must, but it lead me to another question that may be related. In the API documentation it says that the CutEventArgs class contains three things: CutIndexes, Results, and UserState. I do not believe that the contents of UserState are relevant to my task. However, I am currently simply looping through the two graphics I found in Results and adding them to my output Featurelayer. This leaves me wondering, what is this 'CutIndexes' array, and what is its purpose? Am I suppose to use it in some way? The documentation is completely unhelpful regarding the CutIndexes array saying only that it holds the indexes of the new geometries derived from the original. I mean, that sort of sounds like what I want... but then when it says "The indexes of the new geometries..." it never says 'indexes into ... what??' What array or structure are the indexes referencing? The list of graphics in the Results IList? If so, what's the point? What do the values of the CutIndexes values mean - I have two Indexes listed [0] and [1], and each index stores only the value '0' which doesn't tell me a whole lot. This lead to yet another related question: the Geometry Service has a property named 'CutLastResult' ... which is described vaguely as 'Gets the cut last result' ..? Does that mean the 'Results' IList from the last completed CutAsync event? Or is this a different IList containing only the last graphic object of the last set of results? Is there a difference in meaning between Result and Results here? And if the last single result graphic is returned, but multiple geometries are defined by a cut, which is the last one? Thanks for any pointers! Nick
... View more
09-21-2011
08:37 PM
|
0
|
0
|
541
|
POST
|
Hi all. I have implemented a simple interface to use the my local geometry service's cut functionality. I want to allow a user to take an existing polygon and split it into two. Seems simple given that there is an example in the Silverlight interactive SDK that does just this. However, while my code appears to suceed at this task, the returned results from the cut process are only partly correct. If I take a polygon P and draw a line to split it into two non-overlapping portions A and B together which should comprise the entire original geometry of P, I instead get two geometries back from the cut task - A and P? In other words one of the two geometries returned is as I desired one part of the original polygon P, defined by the bisecting line I drew on the map. The other geometry returned should be B, a second polygon also defined by the bisecting line - the other half of P. But instead the second geometry is the entire original polygon P. I guess I could now take my returned polygon A and use it with a reshape function to reshape the returned P-sized geometry to manually create the B polygon I was expecting, but none of the sample code I have seen suggests a need to do this. At first I thought maybe the cut task returns all three geometries - A, B, and just for good measure, P. But I looked at the returned structure during debugging and it only contains the two geometries A and P. This was very confusing at first because my code blindly adds both geometries back to my graphics layer, and the second geometry which was the size of the original P kept getting added on top of A - so I would not see A. I finally realized the issue when I started exploring the returned geometries in an ArcMap edit session... Here is some code:
private void btnStartSplit_Click(object sender, RoutedEventArgs e)
{
// Empty container that gets filled with the polygon geometry I want
// cut by a polyline geometry.
private IList<Graphic> toSplit = new List<Graphic>();
// The source of the graphics used during cutting
GraphicsLayer editsMapLayer = ((GraphicsLayer)MainPage.CPMap.Layers["GraphicsLayer_PLUSelection"]);
// Look for the polyline I drew earlier, of which there will only be one
// because without the polyline, we cannot perform the cut...
//
// Start by getting a collection of all graphics in the graphics layer
GraphicCollection tEdits = editsMapLayer.Graphics;
// Then return only the geometries (of which there will be 0 or 1) where the type is
// ESRI....Polyline
Graphic theLine = tEdits.Where(g => g.Geometry.GetType().FullName == "ESRI.ArcGIS.Client.Geometry.Polyline").FirstOrDefault();
if (theLine == null) return; // And quit here if there was no line
// Obtain the geometry of that line...
ESRI.ArcGIS.Client.Geometry.Polyline theLineGeom = (ESRI.ArcGIS.Client.Geometry.Polyline)theLine.Geometry;
// I know that there is a polygon in my graphics layer to cut, so I search for it and add
// it to my set of geometries to be cut.
toSplit.Add(tEdits.Where(g => g.Geometry.GetType().FullName == "ESRI.ArcGIS.Client.Geometry.Polygon").FirstOrDefault());
// Create a new geometry service
ESRI.ArcGIS.Client.Tasks.GeometryService geoSvc = new ESRI.ArcGIS.Client.Tasks.GeometryService(MainPage.editorMainMap.GeometryServiceUrl);
// Setup the event handler
geoSvc.CutCompleted += new EventHandler<ESRI.ArcGIS.Client.Tasks.CutEventArgs>(geoSvc_CutCompleted);
// Call the cut process asynchronously passing in the container of one polygon geometry to cut,
// and one polyline geometry with which to cut that polygon geometry.
geoSvc.CutAsync(toSplit,theLineGeom);
}
void geoSvc_CutCompleted(object sender, ESRI.ArcGIS.Client.Tasks.CutEventArgs e)
{
MessageBox.Show("Cut Event Returned At Least!");
// I will be adding the returned geometries as new graphics to the SubAreas Featurelayer of my map.
FeatureLayer subareaMapLayer = ((FeatureLayer)MainPage.CPMap.Layers["SubAreas"]);
// Featurelayer save-event-handlers
subareaMapLayer.SaveEditsFailed += new EventHandler<ESRI.ArcGIS.Client.Tasks.TaskFailedEventArgs>(subareaMapLayer_SaveEditsFailed);
subareaMapLayer.EndSaveEdits += new EventHandler<ESRI.ArcGIS.Client.Tasks.EndEditEventArgs>(subareaMapLayer_EndSaveEdits);
subareaMapLayer.BeginSaveEdits += new EventHandler<ESRI.ArcGIS.Client.Tasks.BeginEditEventArgs>(subareaMapLayer_BeginSaveEdits);
// This is where I find I will loop two times, once for each returned geometry...
// one geometry (A from my description above) is correct, and one (P) is not. There
// does not appear to be a third geometry (B)...
foreach (Graphic g in e.Results)
{
// Give the geometry/graphic a default symbol
g.Symbol = MainPage.MainGrid.Resources["DefaultFillSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol;
// Set some attributes on the geometry/graphic...
g.Attributes["SubareaID"] = "{" + Guid.NewGuid().ToString() + "}";
g.Attributes["PlanningLandUnitID"] = OriginPlanningLandUnitId;
g.Attributes["LandUseID"] = Convert.ToInt32(OriginPlanningLandUnitUseId);
g.Attributes["parent_subareaid"] = SplitPractice.Description.ToString();
// Add the new graphic to the Featurelayer
subareaMapLayer.Graphics.Add(g);
// Save the edit
subareaMapLayer.SaveEdits();
} // Process next geometry/graphic in return set
subareaMapLayer.Update();
}
Aside from the interactive SDK, is there anywhere else I can look for examples on what I am supposed to do to use the cut command of my geometry service? What geometries exactly I should expect back from the cut command? Thanks for any input! Nick Floersch
... View more
09-21-2011
01:30 PM
|
0
|
8
|
3055
|
POST
|
No clue except that your feature layer might be read-only. Check that in your code : if (SubAreaLayer.IsReadOnly) MessageBox....... It must have been the 2:30am brain fart... A) Thanks so much for the reply. The result that retuned WAS "yes, this is read only" ... which lead me to triple-check the FeatureLayer... B) I quickly noticed, um, the URL is wrong for the layer: http://SOMESERVER/ArcGIS/rest/services/Editing/SubAreas/MapServer/0 Should Be http://SOMESERVER/ArcGIS/rest/services/Editing/SubAreas/FeatureServer/0 And yet I might have spent hours more looking at the code and not the map services because I was so convinced they were setup right... which they are... but I was using the wrong rest endpoint. Thank you!!! Nick
... View more
09-15-2011
05:44 AM
|
0
|
0
|
192
|
POST
|
Hi all, I am trying to duplicate features, as graphics, one at a time, as selected by a user, from a 'read only' FeatureLayer into a 'work space' FeatureLayer. Honestly this seems like it should be easy, but I'm missing something. The code I am posting below compiles and runs. The graphics objects are not null and appear properly defined. I'm doing only a shallow copy of the source feature graphic to create the duplicate, but I have no idea if that is a problem because ... despite having event handlers for SaveEditsFailed, EndSaveEdits, and BeginSaveEdits, when I finally call SaveEdits(), absolutely nothing happens as far as I can tell. I am trying to call SaveEdits(), and then just in case I'm way off, I'm calling the Save() command in my Editor object on the map. Despite the three event handlers that seem like I should at least see one of them called, and each event handler with a MessageBox and breakpoint, the event handlers never get called. Yes the FeatureLayer "SubAreas" that I am trying to save to is set as editable on the server, and is valid. I tried "AutoSave = true" for it, but had the same result, so that is set to false now. When I call SubAreaLayer.Graphics.Insert(...) I can see, after multiple calls, the number of graphics objects inside of the graphics collection for SubAreaLayer grows. But it never saves the graphics back to the FeatureLayer... when execution of the app ends, they all go away. I tried SubAreaLayer.Graphics.Add(...) as well - same result of graphics collection growing over multiple calls, but nothing be saved in the end. Here is my code chunk:
private void AddSubToScenario(Guid LUID, Guid SID)
{
MainPage MP = (MainPage)((MainContainer)App.Current.RootVisual).LayoutRoot.Children[0];
FeatureLayer SubAreaLayer = (FeatureLayer)MP.CPMap.Layers["SubAreas"];
FeatureLayer LandUnitLayer = (FeatureLayer)MP.CPMap.Layers["SplitLinesPLUs"];
SubAreaLayer.SaveEditsFailed += new EventHandler<TaskFailedEventArgs>(SubAreaLayer_SaveEditsFailed);
SubAreaLayer.EndSaveEdits += new EventHandler<EndEditEventArgs>(SubAreaLayer_EndSaveEdits);
SubAreaLayer.BeginSaveEdits += new EventHandler<BeginEditEventArgs>(SubAreaLayer_BeginSaveEdits);
MP.editorMainMap.LayerIDs = new[] { "SubAreas" }; // in case it matters?
Graphic copiedFeature = new Graphic();
Graphic sourceFeature = LandUnitLayer.SelectedGraphics.FirstOrDefault();
copiedFeature.Geometry = sourceFeature.Geometry;
copiedFeature.Symbol = sourceFeature.Symbol;
copiedFeature.Attributes["OBJECTID"] = sourceFeature.Attributes["OBJECTID"];
copiedFeature.Attributes["LandUseID"] = sourceFeature.Attributes["LandUseId"];
copiedFeature.Attributes["PlanningLandUnitID"] = sourceFeature.Attributes["PlanningLandUnitId"];
copiedFeature.Attributes["SubareaID"] = Guid.NewGuid();
SubAreaLayer.Graphics.Insert(0, copiedFeature); // I did try '.Add(...)' as well, same result either way.
SubAreaLayer.SaveEdits(); // Nothing Happens! No SaveEdit related events fire? No Errors?
if (MP.editorMainMap.Save.CanExecute(null)) MP.editorMainMap.Save.Execute(null); // Maybe??
SubAreaLayer.Update();
}
void SubAreaLayer_BeginSaveEdits(object sender, BeginEditEventArgs e)
{
MessageBox.Show("Copying Graphic Between Feature Layers Started");
}
void SubAreaLayer_EndSaveEdits(object sender, EndEditEventArgs e)
{
MessageBox.Show("Copying Graphic Between Feature Layers Ended");
}
void SubAreaLayer_SaveEditsFailed(object sender, TaskFailedEventArgs e)
{
MessageBox.Show("Copying Graphic Between Feature Layers Failed");
} And here is the XAML for the FeatureLayer...
<esri:FeatureLayer
ID="SplitLinesPLUs"
Url="http://SOMESERVER/ArcGIS/rest/services/Editing/SplitLinesPLUs/MapServer/0"
Renderer="{StaticResource TransFillSelRenderer}"
OutFields="*"
Mode="SelectionOnly"
SelectionColor="{x:Null}"
Opacity="0.75"
Visible="False">
</esri:FeatureLayer>
<esri:FeatureLayer
ID="SubAreas"
Url="http://SOMESERVER/ArcGIS/rest/services/Editing/SubAreas/MapServer/0"
OutFields="*"
Mode="OnDemand"
Visible="False"
AutoSave="False">
</esri:FeatureLayer>
... View more
09-14-2011
10:24 PM
|
0
|
2
|
2191
|
POST
|
We have implemented the widget for our portal's FLEX map viewer tool. http://portalnyoglecc.stone-env.com/NYGISPortal/bin-debug/index.html If you search for only "Live Data Maps" then you should see 4 layers we are hosting for demonstration purposes. Clicking on one will zoom to the extent of the layer, and then a floating content menu for that extent triangle includes the option to add that layer to the map, so you can see the data on the map. Sometimes it takes a little bit after adding the layer to map for the data to show up, and even then, the only layer that is really obvious when it is added is the Fish Species Richness... as it is polygon, and the other layers are little points. The widget as we have implemented it is still lacking in a few areas: you cannot search for data to add from ArcGIS.com for some reason, and there is no legend system. Still, it does basically work. The portal itself is just at: http://portalnyoglecc.stone-env.com/ Nick
... View more
03-22-2011
01:21 PM
|
0
|
0
|
243
|
Title | Kudos | Posted |
---|---|---|
7 | 01-08-2016 01:25 PM |
Online Status |
Offline
|
Date Last Visited |
11-11-2020
02:23 AM
|