/// <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)
예제 #2
0
        } // 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)