Finding Entities with the MapPoint Web Service Find APIs

In this fourth part of a five-part series on the MapPoint Web Service Find APIs, you will learn how to find custom entity types, how to find entities by properties, and more. This article is excerpted from chapter six of the book Programming MapPoint in .NET, written by Chandu Thota (O'Reilly; ISBN: 0596009062). Copyright © 2007 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 1
February 28, 2008
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Finding Custom Entity Types

MapPoint Web Service has a certain set of methods that find entities using their identities and properties, but these methods can only be used with the custom data uploaded to the MapPoint servers. These methods are particularly useful for queries that depend on nonspatial attributes. For example, if you upload all your ATMs to MapPoint servers and you want to display all ATMs in the city of Chicago, or only the ATM that has the unique identity of 13324, these methods can be either simple non-spatial queries or spatial queries. In this section, let’s look at these find methods that can be used with your custom data.

Find entity by identity

You can use the FindServiceSoap.FindByID method to find entities using their entity IDs. Like any other find method, this method takes a specification object of type FindByIDSpecification and returns a FindResultsobject. TheFindByIDSpecificationobject takes up to 500 IDs as input parameters. Table 6-6 shows the fields exposed on theFindByIDSpecificationobject.

Table 6-6. Fields exposed in the FindByIDSpecification object

Field Description
DataSourceName Data source name as a string
EntityIDs Array of unique entity IDs; only points of interest with matching entity IDs are returned, while the rest are ignored

Filter

The filter (FindFilterobject) to apply to the results, which includes the specific entity type, properties, and values that the returned results must match

 Options

The search options (FindOptionsobject), which may include the range of results and a flag to identify which objects are desired in the returned results

The following code shows how to use theFindByIDmethod:

  //Create a Find Service proxy
  FindServiceSoap findService = new FindServiceSoap();
  //Assign credentials
  . . .

  //Define find by id specification
  FindByIDSpecification findbyidspec = new FindByIDSpecification();

  //Assign a data source name
  findbyidspec.DataSourceName = "MapPoint.FourthCoffeeSample";

  //Apply a filter for entity name
  findbyidspec.Filter = new FindFilter();
  findbyidspec.Filter.EntityTypeName = "FourthCoffeeShops";

  //Now assign the entity IDs to find
  int[] arrayID = {-21835, -21836};
  findbyidspec.EntityIDs = arrayID;

  //Call FindById method
  FindResults foundResults;
  foundResults = findService.FindByID(findbyidspec);

The found entities are returned in the same order that the entity IDs are passed in, but you can override this sorting behavior using theFindFilter.SortProperties. Assuming that you want to sort the ATMs in the previousFindByIDmethod by their associated bank name (assuming that there is a property calledParentBankName), the method call looks as follows:

  //Create a Find Service proxy
  FindServiceSoap findService = new FindServiceSoap();
  //Assign credentials
  . . .

  //Define find by id specification
  FindByIDSpecification findbyidspec = new FindByIDSpecification();

  //Assign a data source name
  findbyidspec.DataSourceName = "MapPoint.FourthCoffeeSample";

  //Apply a filter for entity name
  findbyidspec.Filter = new FindFilter();
  findbyidspec.Filter.EntityTypeName = "FourthCoffeeShops";

  //Specify what properties to be used to sort the found results
  SortProperty[] sortproperties = new SortProperty[1];
  sortproperties[0] = new SortProperty();
  //Assign the property name to be sorted on
  sortproperties[0].PropertyName = "ParentBankName";
  //Specify the sort direction: Ascending or Descending
  sortproperties[0].Direction = SortDirection.Descending;

  //Assign sort specification to the find filter
  findbyidspec.Filter.SortProperties = sortproperties;

  //Now assign the entity ids to find
  int[] arrayID = {-21835, -21836};
  findbyidspec.EntityIDs = arrayID;

  //Call FindById method
  FindResults foundResults;
  foundResults = findService.FindByID(findbyidspec);

As you can see, theSortPropertiesmethod is an array, so you can sort the resulting entities by more than one attribute if needed.

It is important to remember that the points of interest entity identities are not persisted from one version of the MapPoint Web Service to another, so if you hardcode the point of interest entity IDs into your application, when you upgrade to a newer MapPoint Web Service, your application may break. To make it easy to distinguish between positive and negative IDs, all negative entity IDs (such as entity ID -21835 for a coffee shop) are not persisted across versions, while the positive IDs are (such as entity ID 244 for the United States).

Finding entity by properties

Many times, you want to query for entities based on their properties—for example, finding all ATMs in the city of Chicago, or all coffee shops that accept credit cards. In this case, the query is based solely on the entity properties, and you should use the FindServiceSoap.FindByProperty method for this purpose. The FindByProperty method takes a specification object of type FindByPropertySpecification, which takes the queries to find entities using their properties. Table 6-7 shows the fields exposed on theFindByPropertySpecificationobject.

Table 6-7. Fields in the FindByPropertySpecification object

Field Description
DataSourceName Name of the data source as a string
Filter The filter (FindFilterobject) to apply to the results; that is, the specific entity type, properties, and values that the returned results must match
Options The search options (FindOptionsobject), which may include the range of results and a flag to identify which objects are desired in the returned results

The following code shows how to use these expressions to find entities using theFindByPropertymethod:

  //Create a find service soap proxy class
  FindServiceSoap findService = new FindServiceSoap();
  //Assign credentials
  . . .

  //Create find by property specification
  FindByPropertySpecification findbypropspec = new FindByPropertySpecification();

  //Define find by property specification
  findbypropspec.DataSourceName = "MapPoint.FourthCoffeeSample";
  //Assign a filter
  findbypropspec.Filter = new FindFilter();
  //Specify the entity type that you are looking for
  findbypropspec.Filter.EntityTypeName = "FourthCoffeeShops";

  //Now define and assign the expression
  findbypropspec.Filter.Expression = new FilterExpression();
  findbypropspec.Filter.Expression.Text = "PrimaryCity = {0} AND IsWiFiHotSpot"; 
  findbypropspec.Filter.Expression. Parameters = new object[] {"Chicago"};

  FindResults foundResults;
  foundResults = findService.FindByProperty(findbypropspec);

The resulting expression from this code is"PrimaryCity = 'Chicago' AND IsWiFiHotSpot", which means to return only coffee shops in the city of Chicago that have WiFi Hotspots available. Even though the filter expressions look and behave like SQL expressions, there are limitations that you need to be aware of:

  1. The expression text should never contain the values that are being compared, but the text must provide the placeholders for all non-Boolean value types. Placeholders are represented by “{nn}” where n is an integer between 0 and 9.
  2. The comparison operators LIKE and NOT LIKE support only the “Starts with” condition.
  3. Maximum length of the expression text is limited to 2,000 characters.
  4. No more than one level of nesting (parenthesis) is allowed.
  5. A maximum of 10 non-Boolean comparisons and a maximum of 10 sub-clauses are allowed.
  6. A maximum of 50 total comparisons per expression is allowed.

Next, let’s look at an example expression: you want to find all coffee shops in the city of Chicago that have a seating capacity greater than 20 or that are open 24 hours a day whose names start with the letter C. The expression to pass for theFindByPropertymethod would be:(City={0} AND SeatingCapacity>{1}) OR (StoreType={2} AND Name LIKE {3}) with the arguments Chicago, 20, Open 24 Hours and C.

Now that you know how to use the find service APIs, let’s look at some of the common service methods that are relevant to the finding places, addresses, and entities.

Finding Polygons

With the find methods, you have seen how to find places, addresses, and points around a place or address, but all you have been finding so far are points (latitude and longitude coordinates). You may have a requirement to find polygons in situations with queries such as: “find all polygons that contain a point (latitude/longitude)” or “find all polygons that have spatial relationship with a rectangle.” In order to accomplish such tasks, use the FindServiceSoap.FindPolygon method.

To learn more about polygons, refer to Appendix B.

Like any find method in Find Service, theFindPolygonmethod takes theFindPolygonSpecificationobject as an argument and returns a validFindResultsobject. TheFindPolygonSpecificationobject provides a way for you to specify arguments such as data source name and spatial filter. Table 6-8 shows the fields exposed by theFindPolygonSpecificationclass.

Table 6-8. Fields of the FindPolygonSpecification class

Field Description
DataSourceName Name of the data source as a string
Filter The filter (FindFilterobject) to apply to the results, including the specific entity type, properties, and values that the returned results must match
Options The search options (FindOptionsobject), which may include the range of results and a flag to identify which objects are desired in the returned results
SpatialFilter The spatial filter (SpatialFilterobject) to apply to the results

One interesting field from Table 6-8 is theSpatialFilter field; this field is of typeSpatialFilterclass, and it defines the spatial relationship between polygons, points, and rectangles. TheSpatialFilterclass is an abstract class, and there are two classes that derive this abstract class to define two specific spatial relationships:

LatLongSpatialFilter

Defines a spatial filter that returns only polygons that include the point specified by theLatLongobject. This is used in specifying a spatial filter to find polygons that contain a certain point. This class has only one field that takes the target point as aLatLongobject. The following code shows how to specify aLatLongSpatialFilterto find polygons that contain a given set of latitude and longitude coordinates:

  //Create a new instance of LatLongSpatialFilter
  LatLongSpatialFilter filter = new LatLongSpatialFilter();
  //Assign the given latitude and longitude values
  Filter.LatLong = new LatLong();
  Filter.LatLong.Latitude = 47.44;
  Filter.LatLong.Longitude = -122.55;

LatLongRectangleSpatialFilter

Defines a spatial filter that returns polygons related to theLatLongRectanglespecified via theBoundingRectanglefield. The relation between the polygons and the rectangle is determined by thePolygonRectangleRelationfield. This field is of typeSpatialRelationenumeration and has two values that are shown in Table 6-10. TheLatLongRectangleSpatialFilterclass is used in defining a spatial filter to find polygons that fall within or touch a rectangle. The following code shows how to define this spatial filter to find all polygons that fall within a rectangle:

  //Define a new instance of LatLongRectanglSpatialFilter
  LatLongRectangleSpatialFilter rectangleFilter =
        new LatLongRectangleSpatialFilter();

  //Define a bounding rectangle with north east and south west
  //corners
  LatLongRectangle boundingRectangle = new LatLongRectangle();
  boundingRectangle.Northeast = new LatLong();
  boundingRectangle.Northeast.Latitude = 47.44;
  boundingRectangle.Northeast.Latitude =
-122.56;

  boundingRectangle.Southwest = new LatLong();
  boundingRectangle.Southwest.Latitude = 41.44;
  boundingRectangle.Southwest.Latitude =
-119.56;

  //Now assign bounding rectangle to the filter
  rectangleFilter.BoundingRectangle = boundingRectangle;
  //Define the spatial relationship to be
  //"find polygons inside the rectangle"
  rectangleFilter.PolygonRectangleRelation =
                 SpatialRelation.WithinArea;

Now that you know how to define spatial filters, let’s look at theFindPolygonmethod in action, using the relations shown in Table 6-9.

Table 6-9. SpatialRelation enumeration

Item Description
WithinArea Returns all polygons contained entirely within the specified rectangle
TouchesArea Returns all polygons that come into contact with the specified rectangle

Use theFindPolygonmethod to findPolygonsthat either contain a specified point or are spatially related to a rectangle. Theymethod takes theFindPolygonSpecificationobject as an argument, as shown in the following code:

  //Create an instance of FindServiceSoap and assign
  //Credentials
  FindServiceSoap findService
                   
= new FindserviceSoap();
  //Assign your credentials
  . . .

  //Create an instance of FindPlygonSpecification
  FindPolygonSpecification findPolySpec
           = new FindPolygonSpecification();

  //Create a new instance of LatLongSpatialFilter
  LatLongSpatialFilter filter = new LatLongSpatialFilter();
  //Assign the given latitude and longitude values
  Filter.LatLong = new LatLong();
  Filter.LatLong.Latitude = 47.44;
  Filter.LatLong.Longitude = -122.55;

  //Assign the spatial filter to the find polygon specification
  findPolySpec.SpatialFilter=filter;

  //Assign your polygon data source
  findPolySpec.DataSourceName="your polygon data source";

  //Define what kind of entities you are looking for
  FindFilter findfilter = new FindFilter();
  findfilter.EntityTypeName = "your entity name";
  findPolySpec.Filter = findfilter;

  //Call Find Polygon
  FindResults findResults = findService.FindPolygon(findPolySpec);
  //Now get the polygon entities
  foreach(FindResult findResult in findResults.Results)
  {
    
//Get polygons that matched the query
     Console.WriteLine(String.Format(
      "Polygon Entity Matched with ID: {0}",
       findResult.FoundLocation.Entity.ID)
                      );
  }

Now that you have the entity IDs of polygons that match your spatial filter criteria, you can use that information either to render the polygons (covered more in Chapter 8) or to perform any other processing to suit your business needs.

Getting Entities from Latitude/Longitude

We have looked at find service methods that take place names and addresses and return the corresponding latitude/longitude and other entity information. To find entity (or address) information for any given latitude/longitude, use the FindServiceSoap.GetLocationInfo; it gives you entity information for any given latitude and longitude. The GetLocationInfo method takes theGetInfoOptionsobject as an argument, along with a latitude/longitude and a data source name as a string. TheGetLocationInfoobject gives you control to decide which entity types you want using theGetInfoOptions.EntityTypesToReturnfield; you also have the option to obtain addresses for a given latitude/longitude (if available) using theGetInfoOptions. IncludeAddressesflag. The following code shows how to use theGetLocationInfo method:

  //Create a find service soap proxy
  FindServiceSoap findService = new FindServiceSoap();
  //Take an example lat long information that you want to
  //find using GetLocationInfo
  LatLong latlong = new LatLong();
  latlong.Latitude = 47.682;
  latlong.Longitude = -122.132;

  //Define get info options object
  GetInfoOptions options = new GetInfoOptions();
  //I'm looking only for cities
  options.IncludeAllEntityTypes = false;
  options.EntityTypesToReturn = new string[] {"PopulatedPlace"};

  //Define a field to hold returned 
locations
  Location[] returnedLocations;
  //Call GetLocationInfo with "MapPoint.NA" data source
  returnedLocations = findService.GetLocationInfo(latlong, "MapPoint.NA", options);
  //Get entity information
  for(int i = 0; i < returnedLocations.Length; i++)
  {
    
Console.WriteLine(returnedLocations[i].Entity.DisplayName);
  }

When I’m querying for corresponding entities for the latitude/longitude, I limit my query to a city (the entity namePopulatedPlace) using theEntityTypesToReturnfield; it is important to remember that you must set theIncludeAllEntityTypesto false when you request specific entities.

This method is not a direct inverse to theFindServiceSoap.FindAddressmethod, so if you call theFindServiceSoap.FindAddressmethod to obtain latitude/longitude for an address and pass that latitude/longitude to theFindServiceSoap.GetLocationInfomethod, the resulting address won’t match your original address because of the internal representation of the address data; in MapPoint data sources, addresses are stored in address range blocks along the streets, and the interpolation algorithms are used to calculate the address for a given latitude/longitude and vice versa. So, the addresses returned by theFindServiceSoap.GetLocationInfoare approximations of the original address; in fact, this method returns an array of four possible addresses for any given latitude/longitude in increasing order of the distance from the given latitude/longitude.

Please check back next week for the conclusion to this article.

blog comments powered by Disqus
BRAINDUMP ARTICLES

- Microsoft Windows 8 Committed to Cloud Compu...
- Independent Developers Favor Windows Phone 7
- Dell Introduces VMware-based Cloud
- Microsoft and Skype Agree to Acquisition Deal
- Transfer Contacts in Microsoft Outlook
- Zune`s Next Steps
- Safari Books Online Review
- Does Microsoft Get Touch Screens Now?
- Microsoft`s Record Quarterly Earnings Not En...
- Basic Operations and Registers in Assembly
- Assembly Coding within Visual C/C++ IDE
- New Microsoft Office Coming with a Twist
- Microsoft`s FUSE Labs Unveils Spindex Social...
- HP Slate with Windows 7: Dead or Alive?
- Windows Phone 7 Mobile OS to Rival Android a...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 8 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials