public void TestFindAddressCandidatesCannotMatchAddress(string address) { BindRunTime(); // Get the input from the IPropertySet object names = null; object values = null; IPropertySet addressObj = new PropertySetClass(); names = new string[] { "Single Line Address" }; // Get centre point of Envelope for geocode location // Workaround for currnet non Point geometry issue values = new object[] { address }; addressObj.SetProperties(names, values); BNG_Locator bng = new BNG_Locator(); IArray matches = bng.FindAddressCandidates(addressObj); Assert.IsTrue(matches.Count == 0); }
/// <summary> /// Generate an address based on a point. /// </summary> /// <param name="location"></param> /// <param name="returnIntersection"></param> /// <returns></returns> public override IPropertySet ReverseGeocode(IPoint location, bool returnIntersection) { _log.Debug("IReverseGeocode ReverseGeocode"); string matchText; IPropertySet reverseGeocodedResult = new PropertySetClass(); Type factoryType = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment"); System.Object obj = Activator.CreateInstance(factoryType); var srf = obj as ISpatialReferenceFactory3; var wgs84GCS = srf.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984); // Sometimes LatLong is incorrectly identified as BNG so it must be checked if ((location.X > -9 && location.X < 2) && (location.Y > 49 && location.Y < 61)) { location.SpatialReference = wgs84GCS; } // Only supports coords in WGS 84 or BNG if (location.SpatialReference.Name == "GCS_WGS_1984") { #region Project coordinates to BNG accurately // Create Transformation from WGS84 to OSGB86 var geoTrans = srf.CreateGeoTransformation((int)esriSRGeoTransformationType.esriSRGeoTransformation_OSGB1936_To_WGS1984Petrol) as IGeoTransformation; ISpatialReference fromSpatialReference; ISpatialReference toSpatialReference; geoTrans.GetSpatialReferences(out fromSpatialReference, out toSpatialReference); // Use correct coord systems to ensure accuracy var bngPCS = srf.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_BritishNationalGrid); if ((wgs84GCS.FactoryCode != toSpatialReference.FactoryCode) || (bngPCS.GeographicCoordinateSystem.FactoryCode != fromSpatialReference.FactoryCode)) { throw new Exception("invalid geotransformation"); } IGeometry5 geometry; geometry = location as IGeometry5; geometry.SpatialReference = wgs84GCS; geometry.ProjectEx(bngPCS, esriTransformDirection.esriTransformReverse, geoTrans, false, 0.0, 0.0); location = geometry as IPoint; #endregion } else if (location.SpatialReference.Name != "British_National_Grid") { // Unaccepted spatial reference, do not process return reverseGeocodedResult; } TranslateGridReference translate = new TranslateGridReference(); // Translate the BNG coords to a British Grid Reference matchText = translate.GetGridReference(location); object names = null; object values = null; // The values being returned must include a geometry, any extra info fields ("X", "Y", "Addr_type") and at least // one field with the same name as an input field, "BNG" in this case, to hold the result fields, mathcText in this case names = new string[] { "Shape", "X Field", "Y Field", "BNG" , "Addr_type", "Match_addr" }; values = new object[] { location, location.X, location.Y, matchText.ToString(), "BNG", matchText.ToString() }; reverseGeocodedResult.SetProperties(names, values); return reverseGeocodedResult; }
/// <summary> /// Uses the FindAddressCandidates method to geocode a single address /// </summary> /// <param name="address">Input address</param> /// <returns>IPropertySet that contains the matched address</returns> public virtual IPropertySet MatchAddress(IPropertySet address) { _log.Debug("IAddressGeocoding MatchAddress"); IPropertySet resultSet = new PropertySetClass(); try { IArray addressCandidates = FindAddressCandidates(address); if (addressCandidates.Count < 1) throw new Exception(); resultSet = addressCandidates.get_Element(0) as IPropertySet; object names; object values; // Get the name and value of all the properties in the property set resultSet.GetAllProperties(out names, out values); String[] nameArray = names as String[]; object[] valueArray = values as object[]; _log.Debug("MatchAddress Input address columns:" + string.Concat(nameArray)); // Add the Status Field to the Result List<string> matchNames = new List<string>(nameArray); List<object> matchValues = new List<object>(valueArray); matchNames.Insert(1, "Status"); matchValues.Insert(1, "M"); // Set the field names and values for the matched address names = matchNames.ToArray() as object; values = matchValues.ToArray() as object; resultSet.SetProperties(names, values); return resultSet; } catch (Exception ex) { _log.Error("An error ocurred during MatchAddress: " + ex.Message); // Return an empty address match to prevent errors IGeometry emptyPoint = new PointClass() as IGeometry; emptyPoint.SetEmpty(); resultSet.SetProperties(new string[] { "Shape", "Status", "Score", "Match_addr" }, new object[] { emptyPoint, "U", null, null }); return resultSet; } }
/// <summary> /// This method is called when a query is made to the locator. /// This must be implemented in such a way that Single and Multi line searches can be preformaed /// </summary> /// <param name="address">Review code for the structure of this property set</param> /// <returns>A single-line array containing a property set. Review code for the structure of this property set</returns> public override IArray FindAddressCandidates(IPropertySet address) { _log.Debug("BNGLocator IAddressCandidates FindAddressCandidates"); IArray addressCandidates = new ArrayClass(); // Get the input from the IPropertySet object names = null; object values = null; address.GetAllProperties(out names, out values); string[] nameArray = (string[])names; object[] valueArray = (object[])values; _log.Debug("Input address columns:" + string.Concat( nameArray)); //make sure there is at least one value if (nameArray.Length > 0) { string addressValue; if(nameArray.Length == 1) addressValue = valueArray[0].ToString(); else addressValue = valueArray[0].ToString() + "," + valueArray[1].ToString(); _log.Debug("Lookup Value:" + addressValue); Envelope enve = DoMatchLookup(addressValue); // Get centre point of Envelope for geocode location // ONLY Point geometries can be returned successfully Point point = CentrePoint(enve); if (point != null) { // Ensure spatial reference is set on this envelope returned by the search function (point as IGeometry).SpatialReference = base.m_spatialReference; // Build the required output array IPropertySet match = new PropertySetClass(); names = new string[] { "Shape", "Status", "Score", "X", "Y", "XMin", "YMin", "XMax", "YMax", "Match_addr", "Addr_type" }; values = new object[] { point, "M", 100, point.X, point.Y, enve.XMin, enve.YMin, enve.XMax, enve.YMax, addressValue.ToUpper(), "BNG" }; match.SetProperties(names, values); addressCandidates.Add(match); } } return addressCandidates; }