https://www.taltion.nl, https://www.trekhaakkoffer-huren.nl, https://www.fietsendrager-huren.nl, https://www.fietskar-huren.nl
"True skill is when luck becomes a habit"
SWIS
Verwijderd
De afstand tussen A en B is gelijk aan de afstand tussen B en A, als je het dus handig aanpakt is het juist weer de helft van het berekende aantal.
Dit. Iets met X coördinaten. Als je het verste (of het middelste) punt op 0 zet kun je de afstand vanaf de 0 gebruiken om het verschil tussen alle objecten te berekenen. Voorbeeld: Object 1: 40 - Object 2: 50 -> 50-40 = 10. Je kunt de Y coördinaten ook toevoegen als je dat gebruikt.Verwijderd schreef op vrijdag 25 juni 2010 @ 20:16:
Gewoon realtime berekenen?
* voodooless moet er niet aan denken om dat op zijn werk te doen met 900.000.000 individuele posities in een db
Do diamonds shine on the dark side of the moon :?
Dit werkt niet, je kan niet altijd via een derde punt dat exact tussen 2 punten inligt, en anders wordt het zoeken naar dat punt wel je bottleneck.Dreadly schreef op vrijdag 25 juni 2010 @ 20:28:
[...]
Dit. Iets met X coördinaten. Als je het verste (of het middelste) punt op 0 zet kun je de afstand vanaf de 0 gebruiken om het verschil tussen alle objecten te berekenen. Voorbeeld: Object 1: 40 - Object 2: 50 -> 50-40 = 10. Je kunt de Y coördinaten ook toevoegen als je dat gebruikt.
Gewoon ter plekke uitrekenen, en een beetje heuristiek gebruiken om wat resultaten te filteren of goedkoper te rekenen.
{signature}
Dit zou betekenen dat ik voor iedere page-request deze berekening moet maken voor alle records.
Op dit moment weet ik niet precies hoeveel objecten er in de DB (die overigens MySQL is) komen, maar dit zullen er eerder 2000 worden dan 200. Wat dus zomaar richting de 2.000.000 kan gaan.
Op dit moment heb ik een script geschreven dat recursief is en eerst alle objecten ophaalt en dan per opgehaald record alle records in de tabel afloopt om hiervoor de afstand uit te rekenen en deze op te slaan.
https://www.taltion.nl, https://www.trekhaakkoffer-huren.nl, https://www.fietsendrager-huren.nl, https://www.fietskar-huren.nl
Totaal onnodig om dit allemaal te berekenen. Hier zijn spatial indexes voor.Freemann schreef op vrijdag 25 juni 2010 @ 21:03:
het zou de bedoeling moeten zijn dat als men 1 record opvraagt, ook andere records worden getoond die in een straal van 10km liggen.
Dit zou betekenen dat ik voor iedere page-request deze berekening moet maken voor alle records.
Neem gewoon de aftand van 10 km in X en Y richting om het punt heen. Dan krijg je een min_lat, max_lat en min_long,max_long. Hierbinnen kun je dan van alle records de echte afstanden berekenen t.o.v het punt, en alles van meer dan 10 km laten afvallen. Dat kun je prima in SQL doen.
[ Voor 3% gewijzigd door voodooless op 25-06-2010 21:52 ]
Do diamonds shine on the dark side of the moon :?
Had nog nooit van Spatial indexen/query's gehoord, bounding box .....
ga dit ff laten bezinken en me inlezen in de de Spatials
Iemand nog suggesties voor leuk/interessant leesvoer?
https://www.taltion.nl, https://www.trekhaakkoffer-huren.nl, https://www.fietsendrager-huren.nl, https://www.fietskar-huren.nl
Mocht de straal écht belangrijk zijn kan je altijd eerst alles binnen de bouning box ophalen en dat resultatenset alsnog een keertje simpel filteren.
Verwijderd
Hiervoor kun je dus idd een bounding box gebruiken om die globale max goed te krijgen, daarna kun je gewoon sorteren met een hele quick and dirty berekening. Immers gaat het alleen om dichterbij vs verderweg zonder dat de exacte afstand boeiend is.
Normaal is het voor dit soort toepassingen toch niet belangrijk dat het op de cm nauwkeurig is, dus een vrij globale match is prima.
Do diamonds shine on the dark side of the moon :?
Verwijderd
Nee juist niet
Pythagoras is de wortel van de som van het verschil op de X-as tot de 2e macht en het verschil op de Y-as tot de 2e macht. Daar zitten 2 zaken in die niet handig zijn, namelijk worteltrekken en machtsverheffen (wat eigenlijk hetzelfde is maar het gaat ff om het idee).
Voor een sortering op basis van afstand heb je alleen het verschil op de X-as plus het verschil op de Y-as nodig. Dit geeft namelijk exact dezelfde volgorde, zonder deze lastigere berekeningen.
{signature}
http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
heb een index gemaakt, de functie toegevoegd en de geometry Point kolom loc toegevoegd.
Echter krijg ik nu een onverklaarbare foutmelding:
op query#1054 - Unknown column 'sdistances' in 'where clause'
1
2
3
4
5
| SELECT orig.id, distance( orig.loc, dest.loc ) AS `sdistances` FROM gobjectens orig, gobjectens dest WHERE sdistances <10 ORDER BY sdistances LIMIT 10 |
zie pagina 29/29
heb de volgende site gebruikt om de kolom en index aan te maken:
http://maisonbisson.com/blog/post/12147/working-with-spatial-data-in-mysql/
Wie kan de bovenstaande foutmelding verklaren (zal vast wel weer iets heel simpels zijn maar kom er op deze tijd van de avond ff niet meer uit....)?
https://www.taltion.nl, https://www.trekhaakkoffer-huren.nl, https://www.fietsendrager-huren.nl, https://www.fietskar-huren.nl
Je kunt blijkbaar niet naar een alias refereren in de WHERE clausule.Freemann schreef op vrijdag 25 juni 2010 @ 23:31:
#1054 - Unknown column 'sdistances' in 'where clause'
Je moet dus gewoon WHERE distance( orig.loc, dest.loc ) < 10 doen.
[ Voor 61% gewijzigd door P_de_B op 25-06-2010 23:33 ]
Oops! Google Chrome could not find www.rijks%20museum.nl
Do diamonds shine on the dark side of the moon :?
Afhankelijk waar je de coordinaten vandaan haalt, (WGS 84 of andere kaartprojecties) zal je misschien ook moeten corrigeren voor zaken als vergrotende breedte... Berekeningen op navigatie/plattegronden kan best ingewikkeld zijn.
Verwijderd
Kun je een voorbeeld geven van input waarden waarbij dit inderdaad een ander resultaat geeft (qua volgorde), wel kwadrateren vs niet kwadrateren?Voutloos schreef op vrijdag 25 juni 2010 @ 22:50:
Nee, het kwadrateren maakt wel uit. Worteltrekken kan je wel achterwege laten voor enkel volgorde.
{signature}
Steun Elkaar, Kopieer Nederlands Waar!
Oracle heeft standaard spatial in zich (vanaf versie 9)
MSSql heeft vanaf 2008 dat ook.
Progress heeft de PostGIS extensie.
deze drie kunnen dus afstanden berekenen incl rekening houden met krommingen e.d. (Mits spatial reference goed staat)
Als je echt lat/long op gaat slaan (dus GPS (wgs84) coordinaten) kan je daar geen pythagoras op los laten omdat het in graden of uren/minuten zijn, dan heb je wel een spatial db nodig.
mocht het alleen over data in nederland gaan kan je opslaan in RD coordinaten, dat zijn gewoon getallen met elk coordinaat een meter, en dat is zo'n relatief klein stelsel dat de kromming van de aarde er geen invloed op heeft, dus daarop kan je wel pythagorassen.
Of niet natuurlijk...
Als het alleen maar gaat om volgorde, dan kun je dat prima doen. En zoals eerder gezegd: worteltrekken kun je achterwegen laten.giMoz schreef op maandag 28 juni 2010 @ 08:33:
Als je echt lat/long op gaat slaan (dus GPS (wgs84) coordinaten) kan je daar geen pythagoras op los laten omdat het in graden of uren/minuten zijn, dan heb je wel een spatial db nodig.
Wil je exacte afstanden weten, heb je natuurlijk nog steeds geen spatial DB nodig. Met een beetje rekenen kom je er ook, zoals al meerdere mensen en diverse voorbeelden hebben aangetoond.
Ik denk dat het grootste bezwaar hiervan zal zijn dat je die hele benden zal moeten bijhouden. Als je van je locaties een positie aanpast, moet je daarvoor alle afstanden die gerelateerd zijn aan deze positie aanpassen. Dat is een update van duizenden records. Op zich kan dat wel, maar zal een behoorlijke performance penalty zijn. Als je dit soort dingen niet vaak doet, hoeft dat natuurlijk geen deal breaker te zijn.mhaket schreef op maandag 28 juni 2010 @ 09:12:
Wat is overigens het probleem met 2.000.000 records? Dit is peanuts voor een DB.
[ Voor 33% gewijzigd door voodooless op 28-06-2010 09:22 ]
Do diamonds shine on the dark side of the moon :?
Als je lat/long op slaat (wgs84) dan kan je juist niet pythagorassen, om 2 redenen:voodooless schreef op maandag 28 juni 2010 @ 09:19:
Als het alleen maar gaat om volgorde, dan kun je dat prima doen. En zoals eerder gezegd: worteltrekken kun je achterwegen laten.
Wil je exacte afstanden weten, heb je natuurlijk nog steeds geen spatial DB nodig. Met een beetje rekenen kom je er ook, zoals al meerdere mensen en diverse voorbeelden hebben aangetoond.
1. het is geen getal
2. het houdt rekening met de kromming van de aarde, en dan zou je bij berekeningen die wat dichter bij de noordpool of zuidpool liggen ongewenste resultaten krijgen. (en europa zou al dicht genoeg bij de pool liggen om niet meer goed uit te komen)
Of niet natuurlijk...
Daarvoor is de HAVING.P_de_B schreef op vrijdag 25 juni 2010 @ 23:33:
[...]
Je kunt blijkbaar niet naar een alias refereren in de WHERE clausule.
Je moet dus gewoon WHERE distance( orig.loc, dest.loc ) < 10 doen.
Hoezo geen getal: neem gewoon decimale graden (met een paar getallen achter de komma).giMoz schreef op maandag 28 juni 2010 @ 14:33:
Als je lat/long op slaat (wgs84) dan kan je juist niet pythagorassen, om 2 redenen:
1. het is geen getal
Dat maakt niet uit als je alleen geïnteresseerd bent in de volgorde.2. het houdt rekening met de kromming van de aarde, en dan zou je bij berekeningen die wat dichter bij de noordpool of zuidpool liggen ongewenste resultaten krijgen. (en europa zou al dicht genoeg bij de pool liggen om niet meer goed uit te komen)
Het wordt wel anders als je afstanden van totaal verschillende punten wil vergelijken. We hebben het hier echter over de afstand t.o.v van een referentie punt.
Do diamonds shine on the dark side of the moon :?
1 lat is een getal en long is ook een getalgiMoz schreef op maandag 28 juni 2010 @ 14:33:
[...]
Als je lat/long op slaat (wgs84) dan kan je juist niet pythagorassen, om 2 redenen:
1. het is geen getal
2. het houdt rekening met de kromming van de aarde, en dan zou je bij berekeningen die wat dichter bij de noordpool of zuidpool liggen ongewenste resultaten krijgen. (en europa zou al dicht genoeg bij de pool liggen om niet meer goed uit te komen)
2 een boundingbox (wat eigenlijk meer neerkomt op een trapezium achtige vorm) gaat eigenlijk pas echt problemen opleveren als je je daadwerkelijk op de pool bevindt. In alle gevallen is het een erg simpele manier om alvast een eerste filtering op je data te doen. Op de resultaten die je vervolgens terug krijgt kun je duurdere afstandsberekeningen loslaten.
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Ook als je het in native spatial opslaat kan je er een spatial index op leggen die de eerste filtering vor je doet, dan hoef je je daar ook geen zorgen meer over te maken.
Maar alles valt of staat met het de vraag waar je zit, als je alleen maar NL data hebt zou ik voor RD coordinaten gaan, dan kan je gewoon lekker pythagorassen. En is het een stuk behapbaarder.
Of niet natuurlijk...
Volgens mij is distance geen aggregate functie, en dus moet je dat ook niet in de HAVING doen.
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Dat is inderdaad echt perfect voor dit soort zaken. Kun je direct uit de databse SVGs tekenen.PeaceNlove schreef op vrijdag 25 juni 2010 @ 21:21:
Probeer PostgreSQL DB met PostGIS uitbreiding. Die kan dat soort ruimtelijke queries met een spatial index wel voor je regelen.
Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.
A HAVING clause can refer to any column or alias named in a select_expr in the SELECT list or in outer subqueries, and to aggregate functions. However, the SQL standard requires that HAVING must reference only columns in the GROUP BY clause or columns used in aggregate functions. To accommodate both standard SQL and the MySQL-specific behavior of being able to refer columns in the SELECT list, MySQL 5.0.2 and up allows HAVING to refer to columns in the SELECT list, columns in the GROUP BY clause, columns in outer subqueries, and to aggregate functions.
{signature}
Maar dat zegt niet dat je het dan maar moet doen
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Verwijderd
Even een gedachteexperimentje ter verduidelijking:
- Ik ga van noord-Afrika naar Mexico, ik ga dus niet noordelijk, maar wel westwaards. Stel nou dat ik daarmee 180 graden afleg.
- Ik ga van noord-Rusland naar Groenland, ik ga dus niet noordelijk, maar wel westwaards. Stel nou dat ik daarmee 180 graden afleg.
Je ziet, de relatieve latitude/logitude zijn hetzelfde in beide situaties, toch garandeer ik je dat de eerste situatie een veel langere afstand, wellicht zelfs tien keer zoveel afstand afleg als in de tweede.
Bedenk dus goed wat je feitelijk wilt, want relatieve lat/long is een redelijk inhoudsloos stukje data, je kan er alleen iets mee als je ook van ten minste één van de twee locaties de absolute lat/long alleen een absolute latitude is genoeg weet.
edit: de eerste situatie is zelfs maar 130 graden, voor 180 graden moet je in Thailand .i.p.v. Afrika zitten, dan is de afstand dus misschien wel 20 keer zo groot als situatie 2.
Op deze website staan formules om vanuit een set van twee latidutes en longitudes de afstand te berekenen:
Nou alleen nog in een query persenHaversine formula:
R = earth’s radius (mean radius = 6,371km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c
Aan jou de keuze of je dit wel wilt doen in je query taal, of dat je op aanvraag dit in een scriptingtaal uitrekend tussen twee punten.
Je hoeft (als je dit in een tabel gaat opslaan) bij ieder nieuw punt maar 1 berekening met ieder ander punt uit te voeren, dus bij het toevoegen vna entry 7 zul je 6 distance entries moeten toevoegen, bij entry 300 299. Het loopt dus vrij hard op, maar voor een PC geen probleem (zolang het geen miljoenen zijn).
[ Voor 44% gewijzigd door Verwijderd op 29-06-2010 10:04 ]
Pythagoras doen op long/lat coordinaten is niet tof. Hiervoor kun je beter een verkaarting gebruiken van de coordinaten, bijvooreeld de Lambert verkaarting (of de Nederlandse verkaarting, waarvan ik even niet op de naam kom). Hiervan zijn opnieuw hapklare versies te vinden op Wikipedia (zie vooral de referenties).
Als je dus alleen maar punten wilt gebruiken is het misschien zelfs aan te raden om in plaats van een geometry veld een lat en long veld te gebruiken, puur voor de snelheid, dan kan je het namelijk gemakkelijk met andere zaken zoals wellicht een status (online/offline) en categorieen combineren.
Maar toch maar even een voorbeeld met MySQL en geometry
Een tabel met een spatial index:
1
2
3
4
5
6
7
8
| CREATE TABLE `points` ( `id` INT(10) NOT NULL DEFAULT '0', `geo` GEOMETRY NOT NULL, PRIMARY KEY (`id`), SPATIAL INDEX `geo` (`geo`(32)) ) ENGINE=MyISAM ROW_FORMAT=DEFAULT |
Records erin:
1
| INSERT INTO points (id, geo) VALUES ('', GEOMFROMTEXT("POINT(52.4 4.6)")) |
Records eruit:
1
2
3
4
5
6
7
8
| SELECT *, ASTEXT(geo) AS wktvalue, X(geo) AS lat, Y(geo) AS lng FROM points WHERE MBRCONTAINS(GEOMFROMTEXT("LINESTRING(52 5, 54 4)"), geo) AND (6371 * ACOS(COS(RADIANS(52)) # 52 = lat * COS(RADIANS(X(geo))) * COS(RADIANS(Y(geo)) - RADIANS(5)) # 5 = long + SIN(RADIANS(52)) # 52 = lat * SIN(RADIANS(X(geo))))) < 50 # ruwe afstand in km |
Deze afstandberekening is niet extreen precies, maar ik neem aan dat dat niet echt nodig is. Haversine formula.
Als je dit wilt doen met lat / long dan kan zal je het geometry veld moeten vervangen en de bounding box dus iets anders moeten doen, maar daar zou je wel uit moeten komen.
"True skill is when luck becomes a habit"
SWIS