sql >> Databáze >  >> RDS >> Sqlserver

Jak mohu použít prostorové prohledávání okruhu PSČ?

Takže na základě Philova návrhu jsem mnoho z toho přepsal pomocí prostorových. To fungovalo skvěle, potřebujete jen .NET4.5, EF5+ a sql server (věřím, že 2008 a vyšší). Používám EF6 + SQL Server 2012.

Nastavení

Prvním krokem bylo přidat Geography sloupec do mé databáze EventListings tabulka (klikněte na ni pravým tlačítkem -> Návrh). Své umístění jsem pojmenoval:

Dále, protože používám EDM s databází-first, musel jsem aktualizovat svůj model, aby používal nové pole, které jsem vytvořil. Pak se mi zobrazila chyba o nemožnosti převést Geografii na dvojitou, takže jsem to opravil tak, že jsem v entitě vybral vlastnost Location, přešel do jejích vlastností a změnil její typ z double na Geography :

Dotazování v rámci okruhu a přidávání událostí s místy

Pak vše, co musíte udělat, je dotazovat se na kolekci entit takto:

 var events = EventRepository.EventListings
                             .Where(x => x.Location.Distance(originCoordinates) * 0.00062 <= radiusParam); 

Metoda Distance extension získává vzdálenost od aktuálního objektu k „jinému“ objektu, který předáte. Tento další objekt je typu DbGeography . Stačí zavolat statickou metodu a ta vytvoří jedno z těchto štěňat, pak do ní stačí umístit svou zeměpisnou délku a šířku jako bod:

DBGeography originCoordinates = DBGeography.fromText("Point(" + originLongitude + " " + originLatitude + ")");

Takto jsem nevytvořil své původní souřadnice. Stáhl jsem si samostatnou databázi, která měla seznam všech PSČ a jejich zeměpisné šířky a délky. Přidal jsem sloupec typu Geography k tomu také. Jak na to ukážu na konci této odpovědi. Poté jsem se zeptal na kontext PSČ, abych získal objekt DbGeography z pole Location v tabulce PSČ.

Pokud uživatel chce konkrétnější původ než jen PSČ, zavolám rozhraní Google Maps API (přesněji GeoCode) a prostřednictvím webové služby získám zeměpisnou šířku a délku pro konkrétní adresu uživatele a vytvořím objekt DBGeography z hodnoty zeměpisné šířky a délky v odpovědi.

Při vytváření události také používám rozhraní Google API. Před přidáním své entity do EF jsem nastavil proměnnou umístění takto:

someEventEntity.Location = DBGeography.fromText("Point(" + longitudeFromGoogle+ " " + latitudeFromGoogle + ")");

Další tipy a triky a odstraňování problémů

Jak jsem získal metodu prodlužování vzdálenosti?

Chcete-li získat metodu rozšíření Distance musíte přidat odkaz na svůj projekt:System.Data.Entity Poté musíte přidat pomocí:using System.Data.Entity.Spatial; do vaší třídy.

Distance metoda rozšíření vrací vzdálenost s měrnou jednotkou metrů (Myslím, že to můžete změnit, ale toto je výchozí). Zde byl můj parametr poloměru v mílích, takže jsem pro převod provedl nějaké výpočty.

Poznámka :Existuje DBGeography třídy v System.Data.Spatial . Toto je špatný a to by mi nefungovalo. Mnoho příkladů, které jsem našel na internetu, použilo tento.

Jak převést Lat/Long na Geografický sloupec

Takže pokud jste byli jako já a stáhli jste si databázi PSČ se všemi Latitude &Longitude a pak si uvědomil, že nemá sloupec Zeměpis... to by mohlo pomoci:

1) Přidejte do tabulky sloupec Umístění. Nastavte typ na Geografie.

2) Spusťte následující sql

UPDATE [ZipCodes]
SET Location = geography::STPointFromText('POINT(' + CAST([Longitude] AS VARCHAR(20)) + ' ' + CAST([Latitude] AS VARCHAR(20)) + ')', 4326)

Jak zobrazit podrobnosti o položce Zeměpis

Když tedy zadáte dotaz na tabulku EventListings v Sql Server Management Studio poté, co jste vložili nějaké položky DbGeography, uvidíte Location sloupec obsahuje hexadecimální hodnotu jako:0x1234513462346. To není příliš užitečné, když se chcete ujistit, že byly vloženy správné hodnoty.

Chcete-li skutečně zobrazit zeměpisnou šířku a délku mimo toto pole, musíte se dotázat takto:

SELECT Location.Lat Latitude, Location.Long Longitude
FROM [EventListings]



  1. Jak používat MAX v MySQL?

  2. Jak mohu vyloučit horní limit na serveru BETWEEN sql

  3. Yii2 Vícenásobná přiřazení RBAC pro každého uživatele na základě skupin

  4. sp_add_schedule vs sp_add_jobschedule v SQL Server:Jaký je rozdíl?