W ostatnim w poście pokazałem jak odczytać współrzędne geograficzne. Kolejne możliwe pytanie, to jak je przechowywać w bazie danych. Najprostsze podejście to stworzenie dwóch kolumn typu float, dla szerokości i długości geograficznej.
W SQL Server istnieje jednak lepsze rozwiązanie, a mianowicie typ “geography”. Służy on do przechowywania lokalizacji i nie koniecznie wyłącznie pojedynczego punktu. Możliwe jest zapisywanie całych poligonów. Utworzenie tabeli z taką kolumną, nie różni się niczym od pozostałych typów:
CREATE TABLE Locations ( Id int IDENTITY (1,1), Location geography ); GO
Następnie dodanie lokalizacji, opisującej poligon wygląda następująco:
INSERT INTO Locations (Location) VALUES (geography::STGeomFromText('POLYGON((-122.358 47.653 , -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))', 4326));
W celu dodania lokalizacji w formie pojedynczego punktu, należy stworzyć obiekt POINT zamiast powyższego POLYGON:
INSERT INTO Locations (Location) VALUES (geography::STGeomFromText('geography::Point(47.65100, -122.34900, 4326))', 4326));
Zaletą korzystania z geography jest, że wszelkie operacje takie jak znajdowanie odległości między dwoma punktami, są już zaimplementowane. Jeśli chcemy znaleźć części wspólne dwóch lokalizacji wtedy:
DECLARE @g geometry; DECLARE @h geometry; SET @g = geometry::STGeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))', 0); SET @h = geometry::STGeomFromText('POLYGON((1 1, 3 1, 3 3, 1 3, 1 1))', 0); SELECT @g.STIntersection(@h).ToString();
Zwracanie odległości między punktami wygląda następująco:
DECLARE @g geography; DECLARE @h geography; SET @g = geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326); SET @h = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); SELECT @g.STDistance(@h);
Ponadto, SQL Server management studio, ma pewne wsparcie dla typu geography. Wykonując prosty SELECT zobaczymy wyłącznie binarne wartości:
Przechodząc jednak do zakładki “Spatial Results”, zobaczymy całą mapkę:
W przyszłym wpisie, pokażę jak korzystać z tego typu w C# (a konkretnie w Dapper).