/// <summary> /// Return FeatureLayer from ArcGISDynamicMapServiceLayer by lyrID /// </summary> /// <param name="lyr"></param> /// <param name="lyrID"></param> /// <returns></returns> private Layer getSubLayer(VUtils.ArcGIS.SLViewer.VLayer lyr, int lyrID) { var fl = lyr.getSubLayer(lyrID); if (fl == null) { throw new Exception("Can't get FeatureLayer from ArcGISDynamicMapServiceLayer"); } return(fl.lyr); } // private Layer getSubLayer(VUtils.ArcGIS.SLViewer.VLayer lyr, int lyrID)
} // public bool getBoolFromJson(JsonObject js, string key) /// <summary> /// Return FeatureLayer or null from ArcGISDynamicMapServiceLayer by lyrID /// </summary> /// <param name="lyrID">ArcGISDynamicMapServiceLayer sublayer id</param> /// <returns>VLayer with FeatureLayer inside</returns> public VLayer getSubLayer(int lyrID) { if (this.lyrType == "ArcGISDynamicMapServiceLayer") { var ld = new VUtils.ArcGIS.SLViewer.VLayerDescription(); ld.type = "FeatureLayer"; ld.url = string.Format("{0}/{1}", this.lyrUrl, lyrID); ld.proxy = this.proxy; var res = new VUtils.ArcGIS.SLViewer.VLayer(ld); return(res); } else { return(null); } } // private Layer getSubLayer(VUtils.ArcGIS.SLViewer.VLayer lyr, int lyrID)
} // public void Execute(object parameter) /// <summary> /// Executes the relationship query against the layer. /// </summary> /// <param name="parameter">The OnClickPopupInfo from the layer.</param> public void doExecute(object parameter) { // The plan is: // Get the featurelayer and clicked feature from the pop-up. // The PopupItem property of OnClickPopupInfo provides information // about the item currently shown in the pop-up. // Then get feature ID value and put it into ExecuteRelationshipQueryAsync task. // Then get related records ID's and create FeatureLayer from // related table/feature class, filtered by that ID's. // Then show grid for that layer. popupInfo = parameter as OnClickPopupInfo; inputFeature = popupInfo.PopupItem.Graphic; var lyr = new VUtils.ArcGIS.SLViewer.VLayer(popupInfo.PopupItem.Layer); // print layer info to console log(string.Format( "Execute, layer type '{0}', popupInd '{1}', popupDescr '{2}', lyrID '{3}', lyrName '{4}', title '{5}'", popupInfo.PopupItem.Layer.GetType(), popupInfo.SelectedIndex, popupInfo.SelectionDescription, popupInfo.PopupItem.LayerId, popupInfo.PopupItem.LayerName, popupInfo.PopupItem.Title)); log(string.Format("Execute, lyrType '{0}', lyrUrl '{1}'", lyr.lyrType, lyr.lyrUrl)); log(string.Format("Execute, inputFeature.Attributes.Count '{0}'", inputFeature.Attributes.Count)); // we need FeatureLayer if (lyr.lyrType == "FeatureLayer") { // The layer to get related records for. // This is used to get the RelationshipID and Query url. relatesLayer = lyr.lyr as FeatureLayer; } else if (lyr.lyrType == "ArcGISDynamicMapServiceLayer") { var rLyr = getSubLayer(lyr, popupInfo.PopupItem.LayerId) as FeatureLayer; if (relatesLayer != null && relatesLayer.Url == rLyr.Url) { // we're here after relatesLayer.Initialized ; } else { // init new FeatureLayer relatesLayer = rLyr; relatesLayer.Initialized += (a, b) => { if (relatesLayer.InitializationFailure == null) { var info = relatesLayer.LayerInfo; log(string.Format( "Execute, relatesLayer.InitializationFailure == null, info '{0}'", info)); Execute(parameter); } }; // callback relatesLayer.Initialize(); log(string.Format("Execute, relatesLayer.Initialize called, wait...")); return; } // init new FeatureLayer } // if(lyr.lyrType == "ArcGISDynamicMapServiceLayer") else { throw new Exception("Layer type must be FeatureLayer or ArcGISDynamicMapServiceLayer"); } // we have inited FeatureLayer now if (relatesLayer.LayerInfo == null) { throw new Exception(string.Format("Execute, relatesLayer.LayerInfo == null")); } var clickedLayer = new VUtils.ArcGIS.SLViewer.VLayer(relatesLayer); // check FeatureLayer info log(string.Format( "Execute, relatesLayer lyrType '{0}', lyrUrl '{1}'", clickedLayer.lyrType, clickedLayer.lyrUrl)); // get relationship id var rels = relatesLayer.LayerInfo.Relationships; if (rels.Count() <= 0) { log(string.Format("Execute, relationships.count <= 0")); throw new Exception(string.Format("Layer have not relations")); } else if (rels.Count() > 1) { log(string.Format("Execute, relationships.count > 1")); if (relationsListForm.listBox1.Items.Count > 0) { // continue after user input // user selected relID already relationInfo = new VUtils.ArcGIS.SLViewer.VRelationInfo( relationsListForm.listBox1.SelectedItem as string); relationsListForm.listBox1.Items.Clear(); } else { // new query foreach (var r in rels) { var ri = new VUtils.ArcGIS.SLViewer.VRelationInfo(r); relationsListForm.listBox1.Items.Add(ri.descr); } relationsListForm.listBox1.SelectedItem = relationsListForm.listBox1.Items.First(); MapApplication.Current.ShowWindow("Relations", relationsListForm, false, // ismodal (sender, canceleventargs) => { log("relationsListForm onhidINGhandler"); }, // onhidinghandler (sender, eventargs) => { log("relationsListForm onhidEhandler"); if (relationsListForm.listBox1.SelectedItem != null) { Execute(parameter); } }, // onhidehandler WindowType.Floating ); return; // wait for user input } // new query } // rels.count > 1 else // rels.count == 1 { log(string.Format("Execute, relationships.count = 1")); relationInfo = new VUtils.ArcGIS.SLViewer.VRelationInfo(rels.First()); } // ok, we get relation info now log(string.Format( "Execute, getrelid, relationshipID '{0}', rels.count '{1}'", relationInfo.id, rels.Count())); // Get the name of the ObjectID field. objectID = relatesLayer.LayerInfo.ObjectIdField; string objectIDAlias = clickedLayer.getFieldAlias(objectID); log(string.Format("Execute, objectID '{0}', alias '{1}'", objectID, objectIDAlias)); if (objectIDAlias != "") { objectID = objectIDAlias; // because of bug? in Graphic.Attributes[fieldname] } // get key value Object v = null; v = inputFeature.Attributes[objectID]; log(string.Format("Execute, objIdValue.str='{0}'", v)); int objIdValue = -1; try { objIdValue = Int32.Parse(string.Format("{0}", v)); } catch (Exception ex) { // fieldname = 'OBJECTID' but alias = 'Object ID' var ks = string.Join(", ", inputFeature.Attributes.Keys); var vs = string.Join(", ", inputFeature.Attributes.Values); log(string.Format("Execute, inputFeature.AttributesKeys='{0}', values='{1}'", ks, vs)); throw new Exception(string.Format("OBJECTID is not an integer")); } log(string.Format("Execute, objIdValue.int='{0}'", objIdValue)); // Input parameters for QueryTask RelationshipParameter relationshipParameters = new RelationshipParameter() { ObjectIds = new int[] { objIdValue }, OutFields = new string[] { "*" }, // Return all fields ReturnGeometry = true, // Return the geometry // so that features can be displayed on the map if applicable RelationshipId = relationInfo.id, // Obtain the desired RelationshipID // from the Service Details page. Here it takes the first relationship // it finds if there is more than one. OutSpatialReference = MapApplication.Current.Map.SpatialReference }; // Specify the Feature Service url for the QueryTask. queryTask.Url = relatesLayer.Url; // Execute the Query Task with specified parameters queryTask.ExecuteRelationshipQueryAsync(relationshipParameters); // Find the attribute grid in the Pop-up and insert the BusyIndicator attributeGrid = Utils.FindChildOfType <Grid>(popupInfo.AttributeContainer, 3); indicator = new BusyIndicator(); if (attributeGrid != null) { // Add the Busy Indicator attributeGrid.Children.Add(indicator); indicator.IsBusy = true; } log(string.Format("Execute, completed, wait for QueryTask_ExecuteRelationshipQueryCompleted")); } // public void doExecute(object parameter)
} // private void resultsLayer_Initialized(object sender, EventArgs e) /// <summary> /// Get related records ID's from query result, add filtered by ID's layer to map /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void doResultsLayer_Initialized(object sender, EventArgs e) { // Get the FeatureLayer's OID field off the LayerInfo string oidField = resultsLayer.LayerInfo.ObjectIdField; var reslyr = new VUtils.ArcGIS.SLViewer.VLayer(resultsLayer); string oidFieldAlias = reslyr.getFieldAlias(oidField); log(string.Format( "doResultsLayer_Initialized, resultsLayer.oidfield='{0}', alias='{1}'", oidField, oidFieldAlias)); if (oidFieldAlias != "") { oidField = oidFieldAlias; } // Create a List to hold the ObjectIds List <int> list = new List <int>(); IEnumerable <Graphic> RelatedRecords; //Go through the RelatedRecordsGroup and add the Graphic to the IEnumerable<Graphic> foreach (var records in queryResult.RelatedRecordsGroup) { RelatedRecords = records.Value; foreach (Graphic graphic in RelatedRecords) { list.Add((int)graphic.Attributes[oidField]); } } log(string.Format("doResultsLayer_Initialized, relatedRecords.oidList.Count='{0}'", list.Count)); if (list.Count <= 0) { throw new Exception("Haven't related records for that object"); } int[] objectIDs = list.ToArray(); resultsLayer.ObjectIDs = objectIDs; log(string.Format("doResultsLayer_Initialized, ID's set")); // Specify renderers for Point, Polyline, and Polygon features if the related features have geometry. if (resultsLayer.LayerInfo.GeometryType == GeometryType.Point) { log(string.Format("doResultsLayer_Initialized, MapPoint")); resultsLayer.Renderer = new SimpleRenderer() { Symbol = new SimpleMarkerSymbol() { Style = SimpleMarkerSymbol.SimpleMarkerStyle.Circle } }; } else if (resultsLayer.LayerInfo.GeometryType == GeometryType.Polyline) { log(string.Format("doResultsLayer_Initialized, Polyline")); resultsLayer.Renderer = new SimpleRenderer() { Symbol = new SimpleLineSymbol() { Color = new SolidColorBrush(Colors.Red), Width = 2 } }; } else if (resultsLayer.LayerInfo.GeometryType == GeometryType.Polygon) { log(string.Format("doResultsLayer_Initialized, Polygon")); resultsLayer.Renderer = new SimpleRenderer() { Symbol = new SimpleFillSymbol() { Fill = new SolidColorBrush(Color.FromArgb(125, 255, 0, 0)), BorderBrush = new SolidColorBrush(Colors.Red) } }; } log(string.Format("doResultsLayer_Initialized, resultsLayer.Geometry is '{0}'", resultsLayer.LayerInfo.GeometryType)); // Specify a layer name so that it displays on the Attribute table, // but do not display the layer in the Map Contents. string mapLayerName = resultsLayer.LayerInfo.Name + ", related records '" + relationInfo.name + "' for OID " + inputFeature.Attributes[objectID].ToString(); MapApplication.SetLayerName(resultsLayer, mapLayerName); LayerProperties.SetIsVisibleInMapContents(resultsLayer, true); log(string.Format("doResultsLayer_Initialized, SetLayerName '{0}'", mapLayerName)); // Add the layer to the map and set it as the selected layer so the attributes appear in the Attribute table. resultsLayer.UpdateCompleted += resultsLayer_UpdateCompleted; MapApplication.Current.Map.Layers.Add(resultsLayer); } // private void doResultsLayer_Initialized(object sender, EventArgs e)