Of these, the spatial features appeared to have the most impact on the nature of the application. In addition, spatial applications are less widely known and understood than, for example, e-commerce order/entry apps, or inventory apps. So our first task was to brainstorm about possible apps. Please feel free to contribute to this project. I am NOT an expert in SQL Server's spatial features, and have no background in this application domain. In one sense that is good: my experience will be similar to your boss handing you a project to evaluate possible uses for this new cool technology she or he has heard about. But my experience will definitely NOT simulate that of a spatial domain expert who is considering using SQL Server. So feel free to jump in, comment, criticize, add creative insights, etc. PLEASE do. So far this project has gone through the following phases:
We likely want the UI to involve maps. There are other possible spatial apps referenced on the internet, that don't involve maps. But in these cases, the geometry data types appear to model objects in a CAD/CAM type of scenario, or possibly building layouts. These apps seemed somewhat more specialized than map-oriented applications, so I decided to exclude them from consideration. In our initial brainstorming session, it was pointed out that there was a large body of photographs on the web which were geo-coded with location data that might be useful to use. There was also the "coolness" factor to consider. Our initial tentative conclusion was that the app ideally could involve both maps and photos.
Since we are creating a sample app that users will install and play with, the data that it uses needs to be somewhat small and publicly available for free. We also likely want to have the app use a pre-existing database, rather than initializing it in the app. so that rules out a "Model-First" EF app. Others felt that we likely wanted to do a Code-First app because that is where customer interest is, so we tentatively decided on that. Code-First of course rules out the use of Table Valued Functions.
We will likely select a subset of US data, and, likely from this local area, just to facilitate testing, because of our familiarity. Another option that was mentioned was to take geocoded photos and upload those into the app, using spatial SQL INSERT statements. Another option was to get data from some kind of service (Bing maps for example, or the "Dallas" Data Mart).
We discussed a number of sample possiblities. We felt that we wanted more complex queries than just "show me all the stores within x miles of here", so that the app would exercise some of the Spatial SQL capabilities.
Given an airplane flight path, show all photos within a mile of the point on the path where you currently are. Or, show me all the hikes (with photos) within 10 miles of a travel path.
The ADO.Net team blog posting on the June CTP spatial features describes how to install the needed software. Pay attention to the warning about only installing this software on a non-production machine, and if you need to uninstall, read the instructions carefully. I heeded the first bit of advice but not the 2nd, and so had the delightful experience of re-paving my machine.
The ADO.Net team blog on spatial has code that demos one common scenario: "show me all the X's that are within Y {miles | kilometers | meters etc} of my present location". The posting code hard-codes "my location" and it would be cool to pick it up from your phone, but for now, let's limit the number of new features that we implement. Additional queries that we may like to execute include:
I've mentioned photos and maps. We should investigate what is involved in:
Investigating these initial features may disclose other factors we haven't considered, beyond availability of data, complexity of api to access the data, etc.
Can we start by using the app in the ADO.Net team blog on spatial? Its section on Code First with an existing database provides us with a number of points (landmarks) inside the city of Seattle, Washington. We can simulate finding all X's within Y miles of a highway by creating lines using several landmarks as points, and then find all Landmarks with X distance of that line. We can simulate finding all X's within an area by creating a polygon made up of lines. We can create compound SQL queries from the above two items. We can call Bing maps on a given landmark. Finding all photos that satisfy some condition will require some research regarding sources of geo-encoded photos on the internet. Or we could insert such photos ourselves and query against them. Housing listings may require more research, but we can certainly get started. So it looks like we can get started with our feasibility study. Then we can evaluate the results and decide on an actual prototype to implement.
First let's create a Lines class, which will generate a table in the database, and then we will populate it with line instances. Initially these instances will contain just two points, but ultimately we'll want to create lines with multiple points, to reflect the real-world situation with actual highways. So lets add some code to the spatial walkthrough, a new class for Lines, and a DbSet method call for Lines. The modified parts of the code now looks like this:
public
class
Line
{
int
LineID {
get
;
set
; }
string
LineName {
DbGeography LineLocation {
}
SeattleLandmarksEntities : DbContext
DbSet<Person> People {
DbSet<Landmark> Landmarks {
DbSet<Line> Line {
Next we need to instantiate a few lines. Being lazy, I'll just add a few using points that are already defined as Landmarks. This actually turned out to be harder than I initially thought. There are several non-intuitive aspects of the SQL Server Spatial api.
var landmark16 =
new
Landmark
LandmarkID = 16,
Address =
"1400 E. Galer Street"
,
Location = DbGeography.Parse(
"POINT(-122.31249 47.632342)"
),
LandmarkName =
"Volunteer Park"
};
// make a line
var line1 =
LineID = 1,
LineName =
"whatever"
LineLocation = DbGeography.Parse(
"LINESTRING(-122.31249 47.632342, -122.317575 47.665229)"
)
// Get landmarks within 2 miles of the line
var line = context.Line.Find(1);
var distanceInMiles2 = 2.5;
var distanceInMeters2 = distanceInMiles * 1609.344;
var landmarks2 =
from l
in
context.Landmarks
where l.Location.Distance(line.LineLocation) < distanceInMeters
select
Name = l.LandmarkName,
Address = l.Address
Console.WriteLine(
"\nLandmarks within "
+ distanceInMiles2 +
" mile(s) of "
+
line.LineName +
"'s location:"
);
foreach
(var loc
landmarks2)
"\t"
+ loc.Name +
" ("
+ loc.Address +
")"
static
void
getLandmarkDistancesFromGeography(SeattleLandmarksEntities context, DbGeography geo,
Name)
Distance = l.Location.Distance(geo) / 1609.344
"\nLandmark distances from "
Name );
+ loc.Distance +
getLandmarkDistancesFromGeography(context, person.Location, person.Name);
getLandmarkDistancesFromGeography(context, context.Landmarks.Find(15).Location, context.Landmarks.Find(15).LandmarkName);
getLandmarkDistancesFromGeography(context, context.Landmarks.Find(16).Location, context.Landmarks.Find(16).LandmarkName);
getLandmarkDistancesFromGeography(context, context.Line.Find(1).LineLocation, context.Line.Find(1).LineName);
var line2 =
LineID = 2,
"Queen Anne Through Downtown"
"LINESTRING(-122.349755 47.647494, -122.352842 47.6186, -122.334571 47.604009 )"
.......
context.Line.Add(line2);
private
FindLandmarksNearLine(SeattleLandmarksEntities context,
lineID,
double
DistanceInMiles)
var line = context.Line.Find(lineID);
var distanceInMeters2 = DistanceInMiles * 1609.344;
where l.Location.Distance(line.LineLocation) < distanceInMeters2
Distance = l.Location.Distance(line.LineLocation),
Limit = distanceInMeters2,
+ DistanceInMiles +
"'s location: (limit in meters: "
+ loc.Name
+ loc.Limit +
FindLandmarksNearLine(context, 1, 2.5);
FindLandmarksNearLine(context, 2, 0.5);
var landmark17 =
LandmarkID = 17,
""
"POINT(-122.34727 47.64677)"
"Aurora Bridge"
....
context.Landmarks.Add(landmark17);
Now each segment of the line has Landmarks that get selected and that don't. If we were at the stage of doing thorough testing, we'd try adding a Line with a large number of segments, but that's for later.
Polygons
To verify the results of the above code, I thought it would be nice to use Bing Maps to plot all the Landmarks, and the Line (and Polygon). I spent about an hour searching on Bing Maps, and am satisfied this can be done, but did not find a quick app I could modify to do this. I did learn enough to be satisfied that it is feasible to use maps as a spatial interface, which was the goal at the point in the project.
I discovered a blog discussing Spatial data available from the US Census Bureau. The author actually imported the data for a specific county into SQL Server, and provides sample code, including:
In addition, by word of mouth I have heard of numerous other government sources of public domain spatial data. So another feasibility goal is satisfied: the free availability of a "nice" subset of spatial data.
Photos remain to be investigated. There are possible legal issues involved that at least need to be investigated (see issues in Europe with Google's street view photos) and resolved. Residential sales data is a more specialized subset that we'll investigate later.