Suite

Création d'une grille de points définie par l'utilisateur


J'essaie d'écrire du code (en C #, mais n'importe quel langage fera l'affaire) où l'utilisateur définit une zone, basée sur Min/Max Long/Lat, et spécifie une distance entre les points en mètres, et le code renvoie une table de long/ lats (WGS84/ESPG:4326) pour créer une grille.

J'ai écrit du code il y a quelque temps que j'avais l'impression de faire le travail, mais après un peu d'analyse, assez à la hauteur du travail. Veuillez consulter le code ci-dessous:

décimal minX = -74,002747535706M; décimal minY = 40,722282672831M; décimal maxX = -73,98386478424M ; décimal maxY = 40,733470232685M ; distance décimale = 100 ; décimal x = 0,0M ; décimal y = 0,0M ; longueur décimale = 0,0M ; longueur décimaleAugmentation = 0,0M ; augmentation décimalePourcentage = 0,0M ; entier je = 0; décimal yIncrément = distance / (décimal)111111.111111; DataTable dt = new DataTable(); dt.Columns.Add("Longitude" , Type.GetType("System.Decimal")); dt.Columns.Add("Latitude" , Type.GetType("System.Decimal")); y = minY; while (y < maxY) { while (x < maxX) { longueur = (décimal)111,325 * (décimal)Math.Cos((double)y * (double)0,0174532925199433); augmentationPourcentage = (décimal)0,001 / longueur * 100 ; longueurAugmentation = augmentationPourcentage / 100 * distance ; x += augmentation de la longueur ; je++ ; DataRow dr = dt.NewRow(); dr["Longitude"] = x; dr["Latitude"] = y; dt.Lignes.Ajouter(dr); } y += yIncrément; x = minX; } renvoie dt;

Ce qui précède fonctionne assez bien. Il retourne long/lats séparés de 100m de lat, mais de 90m de long. Quand je change ledistanceà 25 m, il sépare la latitude de 25 m, mais la longitude de 22,3 m.

ÉDITER: Solution de version C Sharp basée sur la réponse de yosukesabai :

rayon int = 6378137; double pi = Math.PI; double deg2Rad = pi / 180 ; double dst2Lat = 360 / (2 * pi * rayon); DataTable dt = new DataTable(); dt.Columns.Add("ID" , typeof(int)); dt.Columns.Add("Longitude", Type.GetType("System.Decimal")); dt.Columns.Add("Latitude", Type.GetType("System.Decimal")); x = minX; y = minY; while (y < maxY) { double rLat = rayon * Math.Cos(deg2Rad * y); double dst2Lon = 360 / (2 * pi * rLat); tandis que (x < maxX) { i++; x += dst2Lon * distance ; DataRow dr = dt.NewRow(); dr["ID"] = je; dr["Longitude"] = x; dr["Latitude"] = y; dt.Lignes.Ajouter(dr); } x = minX; y += dst2Lat * distance ;

Toute aide ici serait fantastiquement utile!

Salutations

UN M


J'ai adopté l'approche d'ASPMapper, mais au lieu de faire des calculs par moi-même, j'ai utilisé le package géodésique de PROJ.4 (python binding pyproj, http://code.google.com/p/pyproj/).

de pyproj import Geod minX = -74.002747535706 # en degrés minY = 40.722282672831 maxX = -73.98386478424 maxY = 40.733470232685 distance = 100 # en mètres g = Geod(ellps='WGS84') coords = [] lon,lat = minX,minY tandis que lat < maxY : while lon < maxX : coords.append((lon,lat)) east = g.fwd(lon, lat, 90, distance) lon, lat = east[:2] lon = minX north = g.fwd( lon, lat, 0, distance) lon,lat = nord[:2] pour lon,lat en coords : print lon, lat

MODIFIÉ

à partir de l'importation mathématique pi, cos minX = -74.002747535706 # en degrés minY = 40.722282672831 maxX = -73.98386478424 maxY = 40.733470232685 distance = 100 # en mètres # rayon de la terre, ne dites à personne que je n'utilise pas wgs84 :pr = 6378137 deg2rad = pi / 180 # facteur pour convertir le mètre en degré de latitude dst2lat = 360 / (2*pi*r) coords = [] # commence par le coin LL lon,lat = minX,minY # marche vers le nord tandis que lat < maxY : # rayon du cercle of latitude rlat = r * cos(deg2rad * lat) # facteur pour convertir le mètre en degré de longitude dst2lon = 360 / (2*pi*rlat) # marche vers l'est tandis que lon < maxX: # stocke les résultats coords.append((lon, lat)) # aller au mètre de distance à l'Est lon += dst2lon * distance # fait avec un parallèle de latitude # préparer pour le prochain parallèle lon = minX # revenir au bord ouest lat += dst2lat * distance # aller mètre de distance au Nord pour lon ,lat in coords: print lon, lat

Révisé à nouveau

Maintenant, j'ai essayé d'incorporer l'excentricité de la terre définie dans WGS84, au lieu de l'approximation de la sphère. Au nord/sud, j'ai eu une très bonne précision (7 chiffres environ) mais sur la ligne de latitude j'ai toujours une précision de 4 chiffres…

à partir de l'importation mathématique pi, cos, sin, sqrt minX = -74.002747535706 # en degrés minY = 40.722282672831 maxX = -73.98386478424 maxY = 40.733470232685 distance = 100 # en mètres # grand axe et inverse de l'aplatissement de la terre, maintenant j'utilise WGS a, invf = 6378137.0, 298.257223563 # facteur de conversion entre degré et radians deg2rad = pi / 180 # excentricité de la terre f = 1/invf e = sqrt(f*(2-f)) # courbure méridienne à la latitude moyenne de toute la boîte midY = . 5*(minY+maxY) r_meridional_mid = a * (1 - e*e) / ((1 - (e*sin(midY * deg2rad))**2)**1.5) # facteur pour convertir le mètre en degré de latitude , à la latitude médiane dst2lat_mid = 360 / (2*pi*r_meridional_mid) coords = [] # commence par le coin LL lon,lat = minX,minY # marche vers le nord en lat < maxY : # courbure normale à la latitude r_normal = a / sqrt(1-(e*sin(lat*deg2rad))**2) # rayon du cercle de latitude rlat = r_normal * cos(deg2rad * lat) # facteur pour convertir le mètre en degré de longitude dst2lon = 360 / (2* pi*rlat) # marche vers l'Est tandis que e lon < maxX: # stocker les résultats coords.append((lon,lat)) # aller au mètre de distance vers l'Est lon += dst2lon * distance # effectuée avec un parallèle de latitude # préparer le prochain parallèle lon = minX # procéder approximativement à mi-distance au nord lat_tmp = lat + dst2lat_mid * distance * .5 # obtenir la courbure méridienne à la latitude médiane d'une rangée r_meridional = a * (1 - e*e) / ((1 - (e*sin(lat_tmp * deg2rad))** 2)**1.5) # facteur pour convertir le mètre en degré de latitude dst2lat = 360 / (2*pi*r_meridional) # procéder au nord en utilisant la courbure au milieu de la cellule lat += dst2lat * distance print "lon,lat" pour lon,lat en coords: print "%s,%s" % (lon, lat)

Révisé (correction du rayon de courbure normale calc)

J'ai trouvé pourquoi j'ai foiré le rayon de courbure normale (j'ai mal copié la formule). Corrigé et la longitude correspond aux résultats avec Proj.4 par comme 9 chiffres. J'ai également "amélioré" la latitude en calculant le rayon de courbure méridienne à la latitude moyenne de la cellule, et non à la latitude moyenne de la boîte entière. C'est encore une approximation, la bonne manière devrait utiliser l'intégration elliptique ou quelque chose du genre. L'erreur s'accumule dans la direction longitudinale au fur et à mesure que je marche vers le nord, et se termine par une précision à 6 chiffres dans l'entrée de l'échantillon, se référant au proj.4


Voir la vidéo: 6 - Création dune grille. AutoCAD Plant 3D 2016 Modélisation structurelle (Octobre 2021).