// Raised when the locator search completes private void AddressToLocationsCompleted(object sender, AddressToLocationsEventArgs args) { if (args.Results == null || args.Results.Count < 1) // No results found { IsSearching = false; // Reset busy state OnSearchCompleted(); // Raise completed event return; } // check that coordinates returned by extent fields are valid AddressCandidate result = args.Results[0]; double xMin, xMax, yMin, yMax; bool useExtentFields = UseExtentFields; if (UseExtentFields && getExtentFields(result, out xMin, out yMin, out xMax, out yMax)) { if (xMax <= xMin || yMax <= yMin) { // Extent fields are returning invalid coordinates. Disable use of extent fields. useExtentFields = false; } } // Check whether result extents will need to be reprojected using a geometry service SpatialReference locatorSRef = LocatorInfo.SpatialReference; bool needsGeometryServiceProjection = (useExtentFields && ((locatorSRef != null && !locatorSRef.IsWebMercator() && !locatorSRef.IsGeographic()) || (!_map.SpatialReference.IsWebMercator() && !_map.SpatialReference.IsGeographic()))) || (!useExtentFields && _mapUnits == LengthUnits.UnitsDecimalDegrees); List<Graphic> graphicsToProject = new List<Graphic>(); List<LocatorResultViewModel> geographicResults = new List<LocatorResultViewModel>(); foreach (AddressCandidate candidate in args.Results) { // Create the result ViewModel from the result returned from the service LocatorResultViewModel resultViewModel = new LocatorResultViewModel(candidate); // If extent fields are being used, initialize the extent on the service if (useExtentFields && getExtentFields(candidate, out xMin, out yMin, out xMax, out yMax)) { Envelope extent = new Envelope(xMin, yMin, xMax, yMax); if (LocatorInfo.SpatialReference != null) { extent.SpatialReference = locatorSRef; if (!needsGeometryServiceProjection) { // No geometry service needed, so set extent directly if (locatorSRef.IsWebMercator() && _map.SpatialReference.WKID == 4326) extent = (new WebMercator()).ToGeographic(extent) as Envelope; else if (locatorSRef.WKID == 4326 && _map.SpatialReference.IsWebMercator()) extent = (new WebMercator()).FromGeographic(extent) as Envelope; resultViewModel.Extent = extent; } else { // Since results need to be reprojected, add them to collection to be projected // once they've all been gone through graphicsToProject.Add(new Graphic() { Geometry = extent }); _queuedResults.Enqueue(resultViewModel); } } else { resultViewModel.Extent = extent; } } if (resultViewModel.Extent == null && !useExtentFields) { // Initialize the result extent based on the specified extent width if (_gotMapUnits) // check whether map units have been retrieved for the current search { if (!needsGeometryServiceProjection) { initializeResultExtent(resultViewModel); _results.Add(resultViewModel); } else if (_mapUnits != LengthUnits.UnitsDecimalDegrees) { initializeResultExtent(resultViewModel); graphicsToProject.Add(new Graphic() { Geometry = resultViewModel.Extent }); _queuedResults.Enqueue(resultViewModel); } else { // results in a geographic coordinate system (units of decimal degrees) require // special handling because an envelope around the result cannot be calculated // in the result's spatial reference. geographicResults.Add(resultViewModel); } } else { // map units are not yet known, so queue up the result to be added after map units are // determined. _queuedResults.Enqueue(resultViewModel); } } else if (!needsGeometryServiceProjection) { // No projection needed, so the result can be added now _results.Add(resultViewModel); } } if (!needsGeometryServiceProjection) // Check whether result extents need to be reprojected { // No projection needed, so the operation is complete. // Refresh paged collection to update pagination PagedResults.Refresh(); IsSearching = false; // Reset busy state OnSearchCompleted(); // Raise completed event } else if (graphicsToProject.Count > 0) { // result extents need to be reprojected if (_geometryService == null) { _geometryService = new GeometryService(GeometryServiceUrl); _geometryService.ProjectCompleted += GeometryService_ProjectCompleted; } _geometryService.ProjectAsync(graphicsToProject, _map.SpatialReference, _queuedResults); } else { // result extents need to be created in a spatial reference that uses linear units (i.e. // projected coordinate system), then projected back into the current spatial reference. handleGeographicResults(geographicResults); } }
// Initializes the extent of a locator result based on the specified result extent width private void initializeResultExtent(LocatorResultViewModel result) { double extentHeight = _extentWidthInMapUnits / 3; result.Extent = result.Candidate.Location.ToEnvelope(_extentWidthInMapUnits, extentHeight); }