Spacial data geometry type

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Daniel van Seggelen

Daniel van Seggelen

11/02/2017 21:40:59
Quote Anchor link
Ik heb een tabel met een geometry veld.

De functie is geomfromtext.

Een voorbeeld van 1 row, zie ik als ik op wijzigen in phpmyadmin druk


'POLYGON((71.18168640136724 36.49195861816412,71.18560028076172 36.494350433349666,71.19174194335943 36.50730895996088,71.1940536499024 36.50921249389654,71.20061492919933 36.521530151367244,71.2023162841798 36.53117752075201,71.19586944580072 36.5467147827149,71.16728973388672 36.563282012939396,71.15692138671886 36.57472610473627,71.15027618408197 36.58319473266607,71.14428710937506 36.587612152099666,71.12423706054693 36.59239959716797,71.11617279052734 36.59662246704113,71.110336303711 36.6045875549317,71.10877227783209 36.61457443237316,71.1078491210938 36.62884902954113,71.1104125976562 36.65145111083996,71.10903167724621 36.66564559936529,71.10517120361334 36.6751708984375,71.09719085693365 36.687580108642635,71.05976104736334 36.74220275878912,71.05296325683605 36.75279617309576,71.04077148437511 36.77044677734381,71.03369903564464 36.78530120849615,71.0287322998048 36.79067230224615,71.01995086669933 36.809661865234375,71.01715850830078 36.83664321899414,71.01838684082037 36.852745056152344,71.0186996459961 36.864757537841854,71.0131607055664 36.881725311279354,71.00408172607428 36.89732360839855,70.99756622314453 36.906600952148494,70.97681427001959 36.91792678833008,70.95702362060558 36.93212127685547,70.90235137939453 36.94964981079107,70.89722442626953 36.952743530273494,70.89157867431646 36.953460693359375,70.85868835449219 36.96815872192394,70.83393859863287 36.98848724365246,70.8072967529298 37.00197601318365,70.79385375976562 37.0153923034668,70.78425598144526 37.02771377563488,70.76668548583996 37.04189682006836,70.75385284423834 37.054611206054744,70.73582458496094 37.06547927856457,70.71236419677734 37.07621383666992,70.71710205078136 37.09386825561535,70.72151947021484 37.098697662353516,70.73001098632818 37.10400390625006,70.80081939697277 37.12538909912115,70.83810424804688 37.13387298583979,70.85305786132824 37.141250610351676,70.86099243164062 37.15162658691406,70.85707092285168 37.16641616821289,70.8631210327149 37.171394348144645,70.86702728271496 37.17763519287115,70.86686706542969 37.186374664306754,70.85607147216803 37.19466781616211,70.85266113281256 37.201908111572266,70.84901428222662 37.20511627197271,70.83651733398432 37.20804595947277,70.82961273193371 37.21140289306646,70.82763671875006 37.21745681762707,70.81562042236334 37.22917556762695,70.8114013671875 37.23973083496088,70.80228424072271 37.25318908691412,70.78971099853521 37.26210403442394,70.78634643554699 37.27388000488281,70.78272247314464 37.276775360107536,70.80682373046875 37.277301788330135,70.81485748291021 37.281341552734375,70.81623840332037 37.2886848449707,70.81709289550781 37.293460845947266,70.82154083251959 37.29682159423828,70.83209228515636 37.29845428466808,70.8457870483399 37.29278945922863,70.86270141601562 37.29437255859381,70.8719329833985 37.29905319213873,70.87047576904291 37.30951309204107,70.87566375732422 37.312309265136776,70.89360046386719 37.313289642333984,70.90681457519537 37.30573272705078,70.92742156982428 37.30981445312506,70.9312133789063 37.31246566772472,70.9377899169923 37.326686859130916,70.9530639648437 37.33867263793945,70.96315765380871 37.35409164428711,70.96770477294933 37.356811523437614,70.99921417236322 37.3649787902832,71.01068878173828 37.36501312255871,71.01808166503918 37.36796569824219,71.02710723876953 37.376575469970646,71.02914428710949 37.38747406005865,71.03407287597668 37.395420074463004,71.0425186157226 37.40275192260742,71.05181884765636 37.40542221069336,71.067611694336 37.40208816528332,71.08331298828136 37.39230346679699,71.09548950195324 37.38772964477545,71.14640045166021 37.38029098510748,71.17563629150402 37.38212203979492,71.19984436035168 37.392368316650504,71.21194458007812 37.3949928283692,71.23927307128912 37.39723968505871,71.28145599365246 37.3953857421875,71.30579376220703 37.39852523803711,71.31545257568354 37.39558410644531,71.31670379638678 37.3910484313966,71.3101577758789 37.38471221923828,71.29497528076178 37.38022613525396,71.28705596923828 37.37546920776367,71.28683471679699 37.37125015258789,71.29103851318354 37.36457824707037,71.28974914550781 37.36017990112299,71.27915191650396 37.35599136352539,71.25113677978527 37.35282135009777,71.22665405273443 37.3441162109375,71.20819854736334 37.33264541625982,71.19789886474615 37.31738662719732,71.19634246826178 37.30693054199219,71.202392578125 37.28746795654297,71.21271514892578 37.27978134155279,71.24394226074219 37.26496124267578,71.25965118408209 37.26145935058605,71.2726669311524 37.261062622070426,71.29006195068371 37.25634765625,71.3069915771485 37.254852294921875,71.31681060791016 37.25140762329113,71.3193359375 37.24847793579107,71.31261444091797 37.240592956543026,71.3123397827149 37.23638916015631,71.31064605712902 37.23050689697271,71.30936431884766 37.22615814208996,71.30641174316412 37.217082977295036,71.306884765625 37.210605621338004,71.31380462646484 37.199138641357536,71.31552124023438 37.19207000732422,71.31518554687506 37.18364715576166,71.30918884277344 37.1681861877442,71.30998992919922 37.15574264526367,71.3086166381836 37.14609909057623,71.30914306640636 37.13688278198242,71.3118667602539 37.12994384765631,71.32496643066418 37.11399841308605,71.33671569824224 37.0801353454591,71.34899139404308 37.05790328979492,71.35742187499994 37.029747009277344,71.36018371582037 37.022480010986385,71.36710357666027 37.01266479492193,71.38577270507818 36.99665832519537,71.39260864257818 36.98608779907238,71.38890075683594 36.98076629638672,71.37893676757824 36.97710037231451,71.36919403076183 36.97119140625,71.35228729248047 36.95036697387701,71.34382629394543 36.94535446166992,71.33251190185553 36.94327545166027,71.32862091064447 36.940628051757926,71.32713317871094 36.93637084960943,71.35376739501964 36.91397476196295,71.3546142578125 36.90298461914068,71.35136413574219 36.889720916748104,71.34452056884771 36.87891769409191,71.33064270019537 36.86320114135748,71.31948852539062 36.85484695434576,71.30567932128918 36.851322174072266,71.28575897216797 36.85080718994152,71.25354003906256 36.85460662841808,71.24778747558594 36.85282135009771,71.24289703369146 36.847885131835994,71.24264526367188 36.838844299316406,71.24941253662121 36.82844924926758,71.26182556152355 36.819633483886776,71.26367950439459 36.81425476074219,71.25795745849615 36.80268859863287,71.24997711181652 36.79636383056646,71.23321533203136 36.789009094238395,71.22235107421886 36.785427093505916,71.21881866455078 36.77991104125988,71.21971893310547 36.77043533325195,71.23820495605463 36.75890350341797,71.25199890136719 36.752750396728516,71.25804901123041 36.74560546875006,71.26667022705078 36.74248504638666,71.27194976806652 36.73764419555664,71.27148437500006 36.73246002197271,71.26509857177729 36.732200622558594,71.25753021240234 36.734645843505916,71.25239562988287 36.732387542724666,71.25284576416027 36.72899627685547,71.25787353515625 36.72441864013672,71.2562713623048 36.72059249877941,71.25054931640636 36.7188453674317,71.2359390258789 36.720634460449276,71.23085784912115 36.719085693359375,71.2298049926759 36.715347290039176,71.23381805419916 36.703407287597656,71.23182678222662 36.69424819946295,71.2268295288086 36.686775207519645,71.22665405273443 36.6810684204101,71.2311248779298 36.6722526550293,71.23597717285156 36.66879272460943,71.24262237548828 36.65905761718756,71.2632904052735 36.64516067504883,71.28578948974615 36.62201690673834,71.29496002197271 36.61458206176769,71.31832885742188 36.60307312011719,71.34564971923828 36.586452484130916,71.36140441894543 36.58263015747076,71.36968994140625 36.57661056518566,71.37268829345703 36.572875976562614,71.3792572021485 36.56792449951183,71.38696289062511 36.564640045166016,71.40090942382807 36.56162643432617,71.41149139404303 36.557174682617244,71.4110336303711 36.55290222167969,71.4080429077149 36.55183029174816,71.39558410644531 36.55453491210943,71.37394714355474 36.55474090576183,71.3643646240235 36.552261352539176,71.33878326416016 36.54087448120123,71.31842803955084 36.53446197509771,71.30189514160168 36.52355194091797,71.28774261474621 36.52112579345709,71.28182983398449 36.51720809936529,71.27996063232433 36.50761795043945,71.2759475708009 36.49977493286127,71.26815795898432 36.4942512512207,71.25976562499994 36.48325347900402,71.24686431884771 36.47709274291992,71.24159240722668 36.47653961181652,71.2318572998048 36.4786491394043,71.2216796875 36.484298706054744,71.20222473144531 36.48002624511713,71.19345092773438 36.48136901855463,71.18810272216797 36.4844131469726,71.18633270263666 36.48829650878906,71.18168640136724 36.49195861816412))',1

Om deze info eruit te halen met

Quote:
SELECT ST_X(SHAPE), ST_Y(SHAPE) FROM `world`


werkt niet, blijft null.
Hoe krijg ik deze informatie eruit?

Ik wil gewoon de polygon op google maps weergeven.
Gewijzigd op 11/02/2017 21:48:32 door Daniel van Seggelen
 
PHP hulp

PHP hulp

17/12/2018 21:42:55
 
- Ariën -
Beheerder

- Ariën -

11/02/2017 21:47:32
Quote Anchor link
Wat voor database is het? En wat is de structuur?
 
Daniel van Seggelen

Daniel van Seggelen

11/02/2017 21:51:44
Quote Anchor link
Beste Arien,

De structuur van dat veld, zoals ik zei is een Geometry type.
Het is een mysql database
 
- Ariën -
Beheerder

- Ariën -

11/02/2017 21:54:11
Quote Anchor link
Ik was meer op zoek naar de structuur van je tabel 'world'. De entries erin zijn niet echt interessant.
 
Daniel van Seggelen

Daniel van Seggelen

11/02/2017 21:55:35
Quote Anchor link
CREATE TABLE IF NOT EXISTS `world` (
`OGR_FID` int(11) NOT NULL AUTO_INCREMENT,
`SHAPE` geometry NOT NULL,
`id_0` decimal(10,0) DEFAULT NULL,
`iso` varchar(3) DEFAULT NULL,
`name_0` varchar(75) DEFAULT NULL,
`id_1` decimal(10,0) DEFAULT NULL,
`name_1` varchar(75) DEFAULT NULL,
`id_2` decimal(10,0) DEFAULT NULL,
`name_2` varchar(75) DEFAULT NULL,
`hasc_2` varchar(15) DEFAULT NULL,
`ccn_2` decimal(10,0) DEFAULT NULL,
`cca_2` varchar(254) DEFAULT NULL,
`type_2` varchar(50) DEFAULT NULL,
`engtype_2` varchar(50) DEFAULT NULL,
`nl_name_2` varchar(75) DEFAULT NULL,
`varname_2` varchar(150) DEFAULT NULL,
UNIQUE KEY `OGR_FID` (`OGR_FID`),
SPATIAL KEY `SHAPE` (`SHAPE`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=329 ;


Maar waar ik de data uit wil halen is alleen van het SHAPE veld
 
Willem vp

Willem vp

11/02/2017 22:23:35
Quote Anchor link
Je shape is een POLYGON, maar st_x en st_y werken alleen op POINT-waardes.
 
Daniel van Seggelen

Daniel van Seggelen

11/02/2017 22:29:31
Quote Anchor link
Ik wil deze data gebruiken voor google maps API.
Nu doe ik dit
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<?php
$sql
= mysqli_query($DBD->conn(),"SELECT  AsText(SHAPE) as deze from world  where name_1 = 'Badakhshan' " ) or die (mysqli_error($DBD->conn()));    
if($obj = $sql->fetch_object()) {

//echo $obj->deze;

echo json_encode($obj->deze);

// dit voor de google maps polygon

var countries = [];


    $.ajax({

        url : "<?=HTML_ROOT?>inc/countries.php?provUrl=" + a + "&ctUrl=" + b + "&dtUrl=" + c,
        cache : true,
        dataType : 'json',
        async : true,

        success : function(data) {
             //alert(data);
        
          
            if (data) {
                
                $.each(data, function(id,country)
                {

                    var
countryCoords;
                    var
ca;
                    var
co;

                    if ('multi' in country)
                    {

                        var
ccArray = [];

                        for (var t in country['xml']['Polygon'])
                        {


                            countryCoords = [];

                            co = country['xml']['Polygon'][t]['outerBoundaryIs']['LinearRing']['coordinates'].split(' ');

                            for (i = 0; i < co.length; i++)
                            {


                                ca = co[i].split(',');

                               countryCoords.push(new google.maps.LatLng(ca[1], ca[0]));    
                            }


                            ccArray.push(countryCoords);
                        }


                        createCountry(ccArray,country);

                    }

                    else
                    {

                        countryCoords = [];

                        co = country['xml']['outerBoundaryIs']['LinearRing']['coordinates'].split(' ');


var
j;
for (j = 0; j < co.length; j++) {
                            ca = co[j].split(',');

                            countryCoords.push(new google.maps.LatLng(ca[1], ca[0]));    
}



                        createCountry(countryCoords,country);
                    }
                });


                toggleCountries();
            }
            
            
 
    
        }
 
    });


function
createCountry(coords, country) {


    var
currentCountry = new google.maps.Polygon({
          map: map,
        paths: coords,
        strokeColor: 'white',
        strokeOpacity: 1,
        strokeWeight: 1,
        fillColor: '#FF0000',
        fillOpacity: .5
    });
    setTimeout(function() {
                map.fitBounds(currentCountry.getBounds()), google.maps.event.trigger(map, "resize")
    },
500);

  //  countries.push(currentCountry);
}
?>

maar dan krijg ik:

Uncaught TypeError: Cannot use 'in' operator to search for 'multi' in POLYGON((71.18168640136724........

Het is toch een object wat ik terugkrijg via ajax? wat doe ik fout"?
- Ariën -:
Gelieve in het vervolg bij code de [code][/code]-tags gebruiken.
Hier kan je meer lezen over de mogelijke opmaakcodes.
Alvast bedankt!
Gewijzigd op 11/02/2017 22:54:31 door - Ariën -
 
Willem vp

Willem vp

11/02/2017 22:52:25
Quote Anchor link
Even een ruwe gok:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
echo json_encode($obj->deze);

Hier maak je het json-object aan. Daar stop je $obj->deze in. Dat is een string.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
if ('multi' in country)

Hier probeer je de inhoud van het json-object te verwerken. Als input heb je een string, maar je behandelt hem alsof het een array is. Dat gaat niet werken.

In de code die de json genereert, zul je denk ik eerst de POLYGON die in $obj->deze zit moeten omzetten naar een array van losse punten. Maar ik sluit niet uit dat dat ook niet gaat werken en dat er iets conceptueels niet goed is aan de code.


Toevoeging op 11/02/2017 23:10:45:

[terzijde]
Is "if ('multi' in country)" uberhaupt correct javascript?
Gewijzigd op 11/02/2017 22:52:45 door Willem vp
 
Ben van Velzen

Ben van Velzen

11/02/2017 23:17:12
Quote Anchor link
Je terzijde: ja, dat is correct, het is equivalent aan if (isset($country['multi'])). Verder ga ik 100% met je mee. Om de gegevens bruikbaar te maken in javascript zul je nog wat mutaties moeten doen op de string.

EDIT: array_key_exists is een betere analogie.
Gewijzigd op 12/02/2017 01:26:44 door Ben van Velzen
 
Daniel van Seggelen

Daniel van Seggelen

12/02/2017 11:30:08
Quote Anchor link
Als ik er een object van wil maken krijg ik:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
var data= JSON.parse(data);

Uncaught SyntaxError: Unexpected token o in JSON at position 1
    at JSON.parse (<anonymous>)


Hoe kan ik het beste de boel omzetten?



Toevoeging op 12/02/2017 11:31:09:

Bedankt,

Dus de string $obj->deze moet omgezet worden naar een object in javascript?
 
Willem vp

Willem vp

12/02/2017 12:45:13
Quote Anchor link
> Hoe kan ik het beste de boel omzetten?

Laten we eerst beginnen met de vraag: ís het uberhaupt nodig de boel om te zetten?

[terzijde]
Ik weet niet voldoende van de Google Maps API om deze vraag te kunnen beantwoorden. We hebben de API vrij snel aan de kant geschoven toen bleek dat in onze situatie het gebruik ervan zo'n 1200 euro per maand (!) zou gaan kosten. Het was dus goedkoper om een eigen OpenStreetMap-server in te richten en daar met OpenLayers tegenaan te praten.

In OpenLayers heb je de mogelijkheid om een WKT-string, zoals je die uit je database krijgt, te gebruiken.

Overigens: om je shape als WKT op te vragen gebruik je de MySQL-functie AsText(). Die is deprecated; om je code toekomstvast te maken, kun je beter ST_AsText() gebruiken.
[/terzijde]

Als de Google Maps API op de een of andere manier WKT kan deserializen, is het wellicht eenvoudiger om dat te doen. Je hoeft dan geen gekke dingen meer uit te halen in je code.

Als de API dat niet kan, zul je je polygoon moeten opsplitsen in losse punten en die als een array van arrays aan json_encode voeren. Iets als:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
$data['points'] = [
                   [71.18168640136724, 36.49195861816412],
                   [71.18560028076172, 36.494350433349666],
                   [71.19174194335943, 36.50730895996088],
                   <enz>
                  ];
echo json_encode($data);

(waarbij je zelf even iets moet bedenken om $data['points'] te vullen).
Gewijzigd op 12/02/2017 12:45:44 door Willem vp
 
Daniel van Seggelen

Daniel van Seggelen

14/02/2017 20:50:39
Quote Anchor link
Het is uiteindelijk gelukt.
bedankt voor de info.

heb het als een array teruggegeven.

Nu een vervolgvraag:

Ik wil de HTML5 geolocation gebruiken, zodat ik van bezoekers hun huidige locatie kan opslaan. Dit lukt wel met

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function getCurLoc(location)
{    
 if (navigator.geolocation)
 {
    
    // bij chrome werkt dit alleen op https
    navigator.geolocation.getCurrentPosition(function(position)
    {    
    var geocoder;geocoder=new google.maps.Geocoder;var latlng=new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
    //alert("Else loop" + latlng);
    geocoder.geocode({'latLng': latlng}, function(results, status)
    {
        //alert(status);
        if (status == google.maps.GeocoderStatus.OK)
        {
                                     if (location == 'curreg') // wanneer men registreerd en hun locatie wil weten
                    {

                        $(".loading-div").show();
                                        $.ajax({
                                            type: "POST",
                                            url: "<?=HTML_ROOT?>inc/current_reg_location.php",
                                            data: {"lat":position.coords.latitude,"lng":position.coords.longitude,"street":street,"nr":nr},
                                            dataType: "json",
                                            encode: !0
                                        }).done(function(e) {
$(".loading-div").hide(),$(".regions.district.adcatselect").empty(),$(".regions.city.adcatselect.valid").empty(),$(".regions.province.adcatselect.valid").empty(),$.ajax({type:"POST",url:"<?=HTML_ROOT?>inc/provinces.php",dataType:"html",encode:!0}).done(function(t){$(".regions.province.adcatselect.valid").html(t),$("<option></option>",{value:e.reg1,text:e.reg1,selected:"selected"}).appendTo(".regions.province"),$("<option></option>",{value:e.reg2,text:e.reg2,selected:"selected"}).appendTo(".regions.city")});
                                              

                                            //    alert(e.reg3);
                                                if (e.reg3 == '' || e.reg3 =='undefined')
                                                {
                                                   $("<option></option>", {value: '', text: '<?=$_SESSION['def']['NO_DISTRICT']?>', selected: 'selected'}).appendTo('.regions.district');    
                                                } else {
                                                  $("<option></option>", {value: e.reg3, text: e.reg3, selected: 'selected'}).appendTo('.regions.district');
                                                }
$("#postcode").val(e.postcode),$("#lng").val(position.coords.longitude),$("#lat").val(position.coords.latitude);
                                                })                                

            
                    }
                }
        }
      }
     }
    }


Ik gebruik dan een ajax call, waarbij ik uit de database kijk naar het dichtbijzijnde provincie en stad aan de hand van mijn oude tabel, met gewoon float waarden in een lng/lat kolom


current_reg_location.php
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
       $var = array();
        $q = mysqli_query($DBD->conn(), "SELECT ( 6371 * acos( cos( radians(".$_POST['lat'].") ) * cos( radians(Latitude) )
                                       * cos( radians(Longitude) - radians(".$_POST['lng'].")) + sin(radians(".$_POST['lat']."))
                                       * sin( radians(Latitude))))
                                        AS distance,Region1, Region2,Region3,Postcode FROM steden order by distance ASC LIMIT 1");
                                        
                                        
        if($s = mysqli_fetch_array($q))
        {
        //update huidige locatie wanneer er een lid is die zich al geverivieerd heeft    
            if ($s['Region3'] == $s['Region2'])
            {
                $s['Region3'] = '';
            }
            echo json_encode(array('reg1' => $s['Region1'],'reg2' =>$s['Region2'], 'reg3' =>$s['Region3'] , 'postcode' =>$s['Postcode']));
        }


Waarom doe ik het niet via de google reverse geolocation?
Omdat deze namen soms anders zijn dat dat ze bestaan in mijn database.

Ik wil dus aan de hand van de long/latitude bekijken wat het dichtbijzijnde provincie en stad is.

Deze code werkt wel, maar ik heb nu over de hele wereld een database met geometry waardes,zoals hierboven vermeld was.

geometry | land | provincie | stad
-----------------------------------


Wat is de juiste query die uitgevoerd moet worden, om te bepalen in welke provincie/stad dat is?
Ik wil namelijk om deze wijze ook gaan filteren op provincie/stad en daarom wil ik dezelfde namen gebruiken die ik in mijn database al heb staan. Vaak klopt het namelijk niet van wat ik van google terug krijg.
 
Willem vp

Willem vp

14/02/2017 22:19:34
Quote Anchor link
Met ST_Distance zou je de afstand kunnen berekenen van het punt waar de gebruiker zich bevindt tot de geometries in de database. Daarvan kun je dan de kortste afstand kiezen. Het is natuurlijk niet nuttig om je hele tabel door te akkeren, want je weet bij voorbaat al dat je niet naar de afstand tot Sydney of Tokio hoeft te kijken als de gebruiker zich in de buurt van Rotterdam bevindt. Daarom zou je een vierkant van een paar vierkante kilometer kunnen maken met de locatie van de gebruiker als middelpunt en alleen de afstanden bepalen tot de plaatsen die geheel of gedeeltelijk binnen dat vierkant liggen.

Ongeveer zoiets:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
SELECT w.stad, w.provincie, w.land,
       ST_Distance (w.geometry, Point($x, $y)) AS afstand
FROM world w
WHERE ST_Intersects(w.geometry, ST_Envelope(Linestring(Point($x - $a, $y - $a), Point($x - $a, $y - $a))))
ORDER BY afstand ASC
LIMIT 1

waar $x en $y de X- en Y-coördinaten van de gebruiker zijn, en $a een door jou te kiezen afstand die de grootte van het zoekgebied bepaalt. Let op dat $a niet in meters is, maar in graden. Ik zou $a dus aanvankelijk niet groter maken dan 1 of 2; dan heb je al enkele tientallen kilometers in alle richtingen (enigszins afhankelijk van waar op de aardbol je je bevindt).
Gewijzigd op 14/02/2017 22:23:05 door Willem vp
 
Daniel van Seggelen

Daniel van Seggelen

14/02/2017 23:47:34
Quote Anchor link
Heel erg bedankt!
Maar zijn een tientallen km, niet overbodig? Kan ik niet gewoon in 0.1 km zoeken of gewoon het dichtbijzijnste lng/lat? Dat doet hij natuurlijk al omdat hij met een order by afstand werkt, maar mijn database bedekt de hele wereld, als het goed is.
 
Willem vp

Willem vp

15/02/2017 00:55:45
Quote Anchor link
> Kan ik niet gewoon in 0.1 km zoeken

Hangt een beetje af van hoe dekkend je database is. Als iemand zich ergens in het buitengebied bevindt (midden in de Flevopolder of in een bootje op het IJsselmeer?), zou het kunnen dat er binnen 0.1 km geen hit is op je database. De afstand die ik heb gegeven is sowieso arbitrair; kies vooral een waarde die in jouw situatie werkt. Kan zijn dat die kleiner of juist groter gekozen moet worden. Of je begint (relatief) klein en als je geen hit krijgt ga je zoeken in een groter gebied.

> of gewoon het dichtbijzijnste lng/lat?

Volgens mij is het probleem daarbij dat je dus voor elk record in je database de afstand tot de user moet bepalen (ik ben ervan uitgegaan dat het geometry-veld een polygoon bevat en geen point, maar misschien is dat een foute aanname). Vandaar dat ik in mijn oplossing een 'envelope' om de gebruiker trek en alleen de afstand bepaal tot plaatsen die binnen die envelope vallen. Ik gok dat dat een betere performance geeft, maar dat zou je kunnen uitproberen.

Als het geometry-veld alleen points bevat, zit je volgens mij met een soortgelijk probleem. Je moet dan evengoed het verschil gaan uitrekenen tussen de x- en y-coördinaten van alle records en je gebruiker. Ook dan lijkt het beperken van je te doorzoeken dataset me wel handig. En wat doe je wanneer je een plaats A hebt waarvan de X-coördinaat het dichtstbij is, en een plaats B met een dichterbij gelegen Y-coördinaat? Dan moet je alsnog voor zowel plaats A als B de hemelsbrede (?) afstand bepalen om te zien welke plaats dichterbij is.
 
Daniel van Seggelen

Daniel van Seggelen

15/02/2017 08:18:37
Quote Anchor link
Bedankt, het is een geometry veld met een POLYGON. Dus duidelijk verder. Erg belangrijk dat het beter voor de performance is. Bedankt voor de antwoorden!

Toevoeging op 15/02/2017 19:27:01:

Nog even een vervolgvraagje.

Ik heb het bijna voor elkaar, maar als ik in dezelfde tabel bijv een provincie wil selecteren, die in meerdere rijen voorkomt, dan krijg ik meerdere geometry waarden

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
        $sql = mysqli_query($DBD->conn(),"SELECT ST_AsText(SHAPE) as deze FROM `world` WHERE Region2Url = 'zilinsky' limit 1" ) or die (mysqli_error($DBD->conn()));    

        $results = array();
        while ($obj = mysqli_fetch_array($sql)) {
        
        
        
            $results[] = $obj['deze'];
        }
        
        
        echo json_encode(array('countryUrl' => '1','provUrl' => $results, 'province' => '1'));


Of ik nu limit 1 of niet doe, ik krijg dezelfde waardes terug.
Ik wil meerdere geometry waardes dus koppelen en in jquery doe haal ik het zo op:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function parsePolygonPaths(svalue)
{
    var result = [];
    var r = /\(([^)]+)\)/g;
    svalue= svalue.slice(9, -1);
    while (matches = r.exec(svalue)) {
       var vals = matches[1].split(',');
       var coords = vals.map(function(val){
          var ll = val.trim().split(' ');
          return new google.maps.LatLng(ll[1], ll[0]);  
       });
       result.push(coords);
    }
    return result;
}
var result = parsePolygonPaths(polygonString);    
         console.log(result);
            var bounds = new google.maps.LatLngBounds();
            // Construct the polygon.
            result.forEach(function(coords){
                  
                  coords.forEach(function(loc){
                      bounds.extend(loc);
                  });
        
                  var poly = new google.maps.Polygon({
                                  paths: coords,
                                  strokeColor: '#FF0000',
                                  strokeOpacity: 0.8,
                                  strokeWeight: 2,
                                  fillColor: '#FF0000',
                                  fillOpacity: 0.35
                            });
                  poly.setMap(map);        
            });
        
           // map.fitBounds(bounds);
            map.panToBounds(bounds);  
            setTimeout(function() {
                        map.fitBounds(bounds), google.maps.event.trigger(map, "resize")
            }, 500);
        //google.maps.event.addDomListener(window, "load", initialize);
            
            }


Dit werkt dus, maar steeds hetzelfde resultaat, meerdere geometry waarden worden niet aan elkaar gekoppeld.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.