Domanda

Sono interessato a scrivere un'applicazione di navigazione semplicistica come progetto per animali domestici. Dopo aver cercato dati cartografici gratuiti, ho optato per US Census Bureau TIGER 2007 Dati mappa linea / Shapefile. I dati sono suddivisi in file zip per singole contee e ho scaricato un singolo dato-mappa delle contee per la mia area.

Quale sarebbe il modo migliore per leggere questi dati mappa in un formato utilizzabile?

Come dovrei:

  • Leggi in questi file
  • Analizzali - Espressione regolare o qualche libreria che può già analizzare questi Shapefile?
  • Carica i dati nella mia applicazione - Devo caricare i punti direttamente in qualche struttura di dati in memoria? Utilizzare un piccolo database? Non ho bisogno di persistenza una volta chiusa l'applicazione dei dati della mappa. L'utente può caricare di nuovo Shapefile.

Quale sarebbe il modo migliore per eseguire il rendering della mappa dopo aver letto i dati nel file Shapefile?

Idealmente mi piacerebbe poter leggere in uno shapefile di dati di una mappa delle contee e renderizzare tutte le polilinee sullo schermo e consentire la rotazione e il ridimensionamento.

Come dovrei:

  • Convertire i punti lat / lon in coordinate dello schermo? - Per quanto ne so lo Shapefile usa longitudine e latitudine per i suoi punti. Quindi ovviamente dovrò convertirli in qualche modo in coordinate dello schermo per visualizzare le caratteristiche della mappa.
  • Rendering dei dati della mappa (una serie di polilinee per strade, confini, ecc.) in modo da poter ruotare e ridimensionare facilmente l'intera mappa?
  • Rendering dell'intera mappa come una serie di "riquadri" quindi vengono visualizzate solo le caratteristiche / linee all'interno dell'area di visualizzazione?

Ex. dei dati TIGER resi come mappa di visualizzazione:
alt text

Chiunque abbia qualche esperienza e conoscenza di quale sia il modo migliore per me di leggere in questi file, come dovrei rappresentarli (database, nella struttura di dati di memoria) nel mio programma e come dovrei rendere (con rotazione / ridimensionamento) il i dati cartografici sullo schermo sarebbero apprezzati.

MODIFICA: per chiarire, non desidero utilizzare alcuna API per mappe di Google o Yahoo. Allo stesso modo, non voglio usare OpenStreetMap. Sto cercando un approccio più da zero che utilizzare quelle API / programmi. Questa sarà un'applicazione desktop .

È stato utile?

Soluzione

Per prima cosa, ti consiglio di usare i File TIGER 2008 .

In secondo luogo, come altri sottolineano, ci sono molti progetti là fuori che già leggono, interpretano, convertono e usano i dati. Costruire il tuo parser per questi dati è quasi banale, quindi, non c'è motivo di esaminare il codice di un altro progetto e provare a estrarre ciò di cui hai bisogno a meno che non preveda di utilizzare il loro progetto nel suo insieme.

Se vuoi iniziare dal livello inferiore

Analisi

Anche costruire il tuo parser TIGER (ragionevolmente facile - solo un DB di segmenti di linea), e anche costruire un semplice rendering (linee, poligoni, lettere / nomi) sarà abbastanza facile. Ti consigliamo di esaminare vari tipi di proiezione delle mappe per fase di rendering. Il più usato (e quindi il più familiare agli utenti) è la Proiezione del mercatore : è abbastanza semplice e veloce. Potresti voler giocare con il supporto di altre proiezioni.

Ciò fornirà un po 'di divertimento in termini di vedere come proiettare una mappa e come invertire quella proiezione (diciamo che un utente fa clic sulla mappa, vuoi vedere il lat / lon che ha fatto clic - richiede l'inversione l'attuale equazione di proiezione).

Rendering

Quando ho sviluppato il mio renderer ho deciso di basare la mia finestra su una dimensione fissa (dispositivo incorporato) e un ingrandimento fisso. Ciò significava che avrei potuto centrare la mappa su un lat / lon, e con il pixel centrale = center lat / lon ad un determinato ingrandimento, e data la proiezione del mercatore avrei potuto calcolare quale pixel rappresentava ogni lat / lon e viceversa.

Alcuni programmi invece permettono alla finestra di variare e invece di usare l'ingrandimento e un punto fisso, usano due punti fissi (spesso gli angoli in alto a sinistra e in basso a destra di un rettangolo che definisce la finestra). In questo caso diventa banale determinare il trasferimento da pixel a lat / lon - sono solo alcuni calcoli di interpolazione. La rotazione e il ridimensionamento rendono questa funzione di trasferimento un po 'più complessa, ma non dovrebbe esserlo in modo considerevole: è ancora una finestra rettangolare con interpolazione, ma gli angoli della finestra non devono necessariamente avere un orientamento particolare rispetto al nord. Questo aggiunge alcuni casi angolari (puoi capovolgere la mappa e visualizzarla come dall'interno della terra, per esempio) ma questi non sono onerosi e possono essere affrontati mentre ci lavori.

Dopo aver completato il trasferimento da lat / lon a pixel, il rendering di linee e poligoni è abbastanza semplice, tranne per i normali problemi di grafica (come bordi di linee o poligoni che si sovrappongono in modo inappropriato, anti-aliasing, ecc.). Ma rendere una brutta mappa di base come quella fatta da molti renderer open source è abbastanza semplice.

Sarai anche in grado di giocare con i calcoli della distanza e del grande cerchio - per esempio una buona regola empirica è che ogni grado di lat o lon all'equatore è di circa 111.1KM - ma uno cambia man mano che ti avvicini a uno dei due polo, mentre l'altro continua a rimanere a 111.1kM.

Archiviazione e strutture

Il modo in cui memorizzi e fai riferimento ai dati, tuttavia, dipende in larga misura da ciò che prevedi di farne. Molti problemi difficili sorgono se si desidera utilizzare la stessa struttura di database per demografia rispetto al routing: una determinata struttura di base di dati e l'indicizzazione saranno veloci per uno e lenti per l'altro.

L'uso dei codici postali e il caricamento solo dei codici postali vicini funziona per progetti di rendering di piccole mappe, ma se hai bisogno di un percorso attraverso il paese hai bisogno di una struttura diversa. Alcune implementazioni hanno database 'overlay' che contengono solo strade principali e percorsi di snap verso l'overlay (o attraverso più overlay: locale, metro, contea, stato, paese). Ciò si traduce in un routing rapido, ma a volte inefficiente.

Rivestimenti

Piastrellare la tua mappa non è in realtà facile. A ingrandimenti più bassi è possibile eseguire il rendering di un'intera mappa e tagliarla. A ingrandimenti più elevati non è possibile eseguire il rendering dell'intero in una sola volta (a causa di vincoli di memoria / spazio), quindi è necessario suddividerlo.

Tagliare le linee ai bordi delle piastrelle in modo da poter rendere i risultati delle singole piastrelle in risultati non perfetti - spesso ciò che viene fatto è il rendering delle linee oltre il confine delle piastrelle (o, almeno i dati dell'estremità della linea vengono mantenuti, sebbene il rendering si ferma quando rileva che è caduto dal bordo) - questo riduce l'errore che si verifica con le linee che sembrano non corrispondere esattamente mentre viaggiano attraverso le tessere.

Vedrai di cosa sto parlando mentre lavori a questo problema.

Non è banale trovare anche i dati che vanno in una determinata tessera: una linea può avere entrambe le estremità al di fuori di una determinata tessera, ma viaggiare attraverso la tessera. Dovrai consultare libri grafici su questo ( Il libro di Michael Abrash è il riferimento fondamentale , disponibile gratuitamente ora al link precedente). Mentre parla principalmente di giochi, qui si applicano le finestre, il ritaglio, i bordi dei poligoni, le collisioni, ecc.

Tuttavia, potresti voler giocare ad un livello superiore.

Dopo aver fatto quanto sopra (adattando un progetto esistente o eseguendo quanto sopra tu stesso) potresti voler giocare con altri scenari e algoritmi.

La geocodifica inversa è ragionevolmente semplice. Inserisci lat / lon (o fai clic sulla mappa) e ottieni l'indirizzo più vicino. Questo ti insegna come interpretare gli indirizzi lungo i segmenti di linea nei dati TIGER.

La geocodifica di base è un problema difficile. Scrivere un parser di indirizzi è un progetto utile e interessante, quindi convertirlo in lat / lon usando i dati TIGER non è banale, ma è molto divertente . Inizia semplice e piccolo richiedendo la corrispondenza esatta di nome e formato, quindi inizia a cercare la corrispondenza "simile" e la corrispondenza fonetica. C'è molta ricerca in questo settore - guarda i progetti sui motori di ricerca per qualche aiuto qui.

Trovare il percorso più breve tra due punti è un problema non banale. Ci sono molti, molti algoritmi per farlo, molti dei quali sono brevettati. Raccomando che se lo provi, procedi con un semplice algoritmo del tuo design, quindi fai qualche ricerca e confronta il tuo design con lo stato dell'arte. È molto divertente se ti piace la teoria dei grafi.

Seguire un percorso e dare preventivamente istruzioni non è facile come sembra al primo arrossire. Dato un insieme di istruzioni con un array associato di coppie lat / lon, "segui" il percorso usando input esterni (GPS o GPS simulato) e sviluppa un algoritmo che dia all'utente istruzioni mentre si avvicinano ad ogni vero incrocio. Nota che ci sono più coppie lat / lon che istruzioni a causa di curve curve, ecc. E dovrai rilevare la direzione di viaggio e così via. Molti casi angolari non vedrai fino a quando non tenterai di implementarlo.

Ricerca punti di interesse. Questo è interessante: devi trovare la posizione corrente e tutti i punti di interesse (non parte di TIGER, crearne uno tuo o ottenere un'altra fonte) all'interno di un una certa distanza (in linea d'aria, o più difficile - distanza in auto) dell'origine. Questo è interessante in quanto devi convertire il database POI in un formato che è facile da cercare in questa circostanza. Non puoi prenderti il ??tempo di scorrere milioni di voci, eseguire il calcolo della distanza (sqrt (x ^ 2 + y ^ 2)) e restituire i risultati. È necessario disporre di un metodo o algoritmo per ridurre prima la quantità di dati.

Venditore ambulante. Routing con più destinazioni. Solo una versione più difficile del routing regolare.

Puoi trovare una serie di link a molti progetti e fonti di informazioni su questo argomento qui .

Buona fortuna, e per favore pubblica qualunque cosa tu faccia, non importa quanto rudimentale o brutta, così altri possono trarne beneficio!

-Adam

Altri suggerimenti

SharpMap è un motore di mapping .NET 2.0 open-source per WinForms e ASP.NET. Questo può fornire tutte le funzionalità di cui hai bisogno. Si occupa dei più comuni formati di dati vettoriali e raster GIS, inclusi gli shapefile ESRI.

la soluzione è:

  • un server geospaziale come mapserver, geoserver, laurea (opensource).

Possono leggere e servire shapefile (e molte altre cose). Ad esempio, il geoserver (se installato) fornisce i dati dagli shapefile TIGER dell'US Census Bureau come demo

  • una libreria cartografica javascript come openlayer (vedi gli esempi in testo del link

Ci sono molti esempi sul web usando questa soluzione

Domanda divertente. Ecco come lo faccio.

Raccolgo la geometria di cui ho bisogno in qualsiasi formato in cui provengono. Ho acquisito dati da USGS, quindi questo equivale a un sacco di:

Ho quindi scritto un programma che "compila" quelle definizioni delle forme in una forma che è efficiente per il rendering. Ciò significa fare qualsiasi proiezione e conversione del formato dei dati necessaria per visualizzare i dati in modo efficiente. Alcuni dettagli:

  • Per un'applicazione 2D, è possibile utilizzare la proiezione desiderata: Proiezioni della mappa .
  • Per il 3D, vuoi convertire quelle latitudini / longitudini in coordinate 3D. Ecco alcuni calcoli su come farlo: trasformazione da coordinate sferiche rispetto alle normali coordinate rettangolari .
  • Suddividi tutte le primitive in un quadrifoglio / ottetto (2D / 3D). I nodi foglia in questo albero contengono riferimenti a tutta la geometria che interseca il riquadro di delimitazione (asse allineato) di quel nodo foglia. (Ciò significa che un pezzo di geometria può essere referenziato più di una volta.)
  • La geometria viene quindi suddivisa in una tabella di vertici e una tabella di comandi di disegno. Questo è un formato ideale per OpenGL. I comandi possono essere emessi tramite glDrawArrays utilizzando i buffer dei vertici ( Vertex Buffer Objects ).
  • Un modello di visitatore generale viene utilizzato per percorrere il quadrifoglio / ottetto. Camminare implica verificare se il visitatore interseca i nodi dati dell'albero fino a quando non si incontra un nodo foglia. I visitatori includono: disegno, rilevamento delle collisioni e selezione. (Poiché le foglie degli alberi possono contenere riferimenti duplicati alla geometria, il camminatore contrassegna i nodi come visitati e li ignora in seguito. Questi segni devono essere ripristinati o altrimenti aggiornati prima di procedere con la camminata successiva.)
  • L'uso di un sistema di partizionamento spaziale (uno degli alberi) e una rappresentazione efficiente in termini di disegno è cruciale per ottenere framerate elevati. Ho scoperto che in questi tipi di applicazioni, vuoi che il tuo frame rate sia il più alto possibile di 20 fps al minimo. Per non parlare del fatto che molte prestazioni ti daranno molte opportunità per creare una mappa più bella. (Il mio è tutt'altro che bello, ma ci arriverà un giorno.)
  • Il partizionamento spaziale aiuta a rendere le prestazioni riducendo il numero di comandi di disegno inviati al processore. Tuttavia, potrebbe arrivare un momento in cui l'utente desidera effettivamente visualizzare l'intero set di dati (forse una visualizzazione iniziale). In questo caso, è necessario un livello di sistema di controllo dei dettagli. Poiché la mia domanda riguarda le strade, do priorità alle autostrade e alle strade più grandi. Il mio codice di disegno sa quante primitive posso disegnare prima che il mio framerate diminuisca. Anche le primitive sono ordinate per questa priorità. Traccio solo i primi elementi x in cui x è il numero di primitive che posso disegnare al framerate desiderato.

Il resto è il controllo della videocamera e l'animazione di tutti i dati che si desidera visualizzare.

Ecco alcuni esempi della mia implementazione esistente:

Immagine http://seabusoforte/assets/Picture%205.png Immagine http://seabusoforte/assets/Picture%207.png

per l'archiviazione locale dei dati della tigre, sceglierei Postgresql con postgis strumenti.

hanno un'impressionante collezione di strumenti, specialmente per te Tiger Geocoder offre un buon modo di importare e usare i dati della tigre.

dovrai dare un'occhiata agli strumenti che interagiscono con i postgis, molto probabilmente una sorta di mapserver

da http://postgis.refractions.net/documentation/ :

  

Ora ci sono diversi strumenti open source che funzionano con PostGIS. Il progetto uDig sta lavorando su un ambiente desktop di lettura / scrittura completo che può funzionare direttamente con PostGIS. Per la mappatura di Internet, l'Università del Minnesota Mapserver può utilizzare PostGIS come fonte di dati. Il toolkit GIS Java di GeoTools ha il supporto PostGIS, così come il GeoServer Web Feature Server. GRASS supporta PostGIS come fonte di dati. Il visualizzatore GIS desktop JUMP Java ha un semplice plug-in per la lettura dei dati PostGIS e il desktop QGIS ha un buon supporto PostGIS. I dati PostGIS possono essere esportati in diversi formati GIS di output usando la libreria OGR C ++ e gli strumenti da riga di comando (e, ovviamente, con il dumper del file Shape in bundle). E ovviamente qualsiasi linguaggio che può funzionare con PostgreSQL può funzionare con PostGIS: l'elenco include Perl, PHP, Python, TCL, C, C ++, Java, C # e altro.

modifica: depite mapserver con la parola SERVER nel suo nome, questo sarà utilizzabile in un ambiente desktop.

Anche se hai già deciso di utilizzare i dati TIGER, potresti essere interessato a OSM (Open Street Map) , perché OSM ha un'importazione completa dei dati TIGER in esso, arricchiti con i dati forniti dagli utenti. Se ti attieni al formato TIGER, la tua app sarà inutile per gli utenti internazionali, con OSM otterrai TIGER e tutto il resto in una volta.

OSM è un progetto aperto che presenta una mappa del mondo libera modificata in modo collaborativo. Puoi ottenere tutti questi dati anche come XML strutturato, eseguire una query per una regione o scaricare l'intero mondo in un file di grandi dimensioni.

Esistono alcuni renderer di mappe per OSM disponibili in vari linguaggi di programmazione, molti dei quali open source, ma c'è ancora molto da fare.

Esiste anche un servizio di routing OSM disponibile. Ha un'interfaccia Web e potrebbe anche essere interrogabile tramite un'API del servizio Web. Ancora una volta, non è tutto finito. Gli utenti potrebbero sicuramente utilizzare un'applicazione di routing desktop o mobile basata su questo.

Anche se non decidi di partecipare a quel progetto, puoi trarne molta ispirazione. Dai un'occhiata al wiki del progetto e alle fonti dei vari progetti software coinvolti (troverai collegamenti ad essi all'interno del wiki).

Puoi anche lavorare con l'applicazione di mappatura della terra visiva di Microsoft e API o utilizzare l'API di Google. Ho sempre programmato commercialmente con i prodotti ESRI e non ho giocato molto con le API aperte.

Inoltre, potresti voler guardare Maker! e Finder! Sono programmi relativamente nuovi ma penso che siano gratuiti. Potrebbe essere limitato all'incorporamento dei dati. Maker può essere trovato qui.

Il problema è che l'elaborazione spaziale è abbastanza nuova nella scala non commerciale.

Se non ti dispiace pagare per una soluzione Software sicuro produce un prodotto chiamato FME. Questo strumento ti aiuterà a tradurre i dati da qualsiasi formato a qualsiasi altro. Compreso KML il formato di Google Earth o renderlo come JPEG (o serie di JPEG). Dopo aver convertito i dati, puoi incorporare google earth nella tua applicazione utilizzando le loro API o semplicemente visualizzare le immagini piastrellate.

Dal momento che FME non è una piattaforma molto potente, durante le tue traduzioni puoi aggiungere o rimuovere parti di dati che non sono necessariamente necessarie. Unisci le fonti se ne hai più di una. Converti coordinate (non ricordo esattamente cosa utilizza Google Earth). Archivia i backup in un database. Ma seriamente, se sei disposto a sborsare qualche soldo, dovresti esaminare questo.

Puoi anche creare flag (molto simili alla tua mappa di esempio) che contengono una posizione (dove metterla) e altri dati / commenti sulla posizione. Queste bandiere sono disponibili in molte forme e dimensioni.

Una semplificazione su un Mercatore o altra proiezione è quella di assumere un fattore di conversione costante per la latitudine e la longitudine. Moltiplicare i gradi di latitudine per 69.172 miglia; per la longitudine, seleziona la latitudine media dell'area della mappa e moltiplica (180-longitudine) per coseno (middle_latitude) * 69.172. Una volta convertito in miglia, puoi utilizzare un altro set di conversioni per arrivare alle coordinate dello schermo.

Questo è ciò che ha funzionato per me nel 1979.

La mia fonte per il numero di miglia per grado.

Quando ho dato questa risposta la domanda era etichettata

" Quale sarebbe il modo migliore per eseguire il rendering di uno Shapefile (dati cartografici) con polilinee in .Net? "

Ora è una domanda diversa ma lascio la mia risposta alla domanda originale.

  

Ho scritto una versione .net che potrebbe disegnare   dati vettoriali (come la geometria di   un file shp) usando GDI + semplice in c #. esso   è stato abbastanza divertente.

     

Il motivo era che dovevamo farlo   gestire diverse versioni di   geometrie e attributi con molto   di ulteriori informazioni in modo che potremmo   non utilizzare un componente della mappa commerciale o   uno open source.

     

La cosa principale quando si fa questo è   stabilire una finestra e   tradurre / trasformare le coordinate WGIS84   a un downscale e GDI + x, y   coordina e aspetta con la proiezione   se hai persino bisogno di riproiettare affatto.

Una soluzione è usare MapXtreme. Hanno API per Java e C #. L'API è in grado di caricare questi file e renderli.

Per Java:

http: //www.mapinfo.com/products/developer-tools/desktop%2c-mobile-%26-internet-offering/mapxtreme-java

Per .NET:

http: //www.mapinfo.com/products/developer-tools/desktop%2c-mobile-%26-internet-offering/mapxtreme-2008

Ho usato questa soluzione in un'applicazione desktop e ha funzionato bene. Offre molto di più del solo rendering delle informazioni.

Ora farlo da zero potrebbe richiedere del tempo. Hanno una versione di valutazione che è possibile scaricare. Penso che stampa solo "MAPXTREME" sulla mappa come filigrana, ma è completamente utilizzabile altrimenti

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top