Chapter 4. Geolocation and Mapping APIs

文章推薦指數: 80 %
投票人數:10人

Chapter 4. Geolocation and Mapping APIs Chapter 3 introduced us to using the W3C Geolocation API to collect location information from the user's browser ... Skiptomaincontent HTML5GeolocationbyAnthonyT.Holdener GetfullaccesstoHTML5Geolocationand60K+othertitles,withfree10-daytrialofO'Reilly. There'salsoliveonlineevents,interactivecontent,certificationprepmaterials,andmore. Startyourfreetrial Chapter 4. GeolocationandMappingAPIsChapter 3introducedustousingtheW3C GeolocationAPItocollectlocationinformationfromtheuser’sbrowserwith JavaScriptcode.Althoughthatisthewholepointofthisbook,itisnot extremelyusefultocollectgeolocationinformationunlessyou,the developer,aregoingtodosomethingwithit.Oneeffectiveapplicationfor collectingauser’slocationistoplacethatpointonamap.Let’sfaceit, mappingalocation(ormultiplelocations)isacommonthingtodointhe worldofGIS.Therearemanysolutionsavailableforweb-mappingapplications—GoogleMaps JavaScriptAPIV3,BingMapsAJAX Control,Version7.0,EsriArcGIS JavaScriptAPI2.2,YahooMapsAJAXAPI,and OpenStreetMapAPI v0.6tonameafew(morethanafewactually).MostoftheAPIs availabletodowebmappingareverysimilarinnature.Becauseofthis,I havedecidedtofocusonjustacoupleoftheAPIsavailable,andleaveit uptoyoutopicktheAPIthatbestsuitsyourneeds.AftergivingyouatasteoftheseAPIsforuseinyourapplications, wecanthenexplorewhattodowiththeinformationyouhavecollectedso thatitcanbereferencedbyotherapplicationsorreplottedinthefuture. Thisisasimportantasbeingabletomapthegeolocationsbeingcollected, sincemostGISapplicationsaregoingtobeinterestedinmorethanasingle user’spointinformation.Tothisend,wewilllookatdifferentwaysto saveourgeolocationinformationsothatitcanbeconsumedbytheseother applications.AGoogleMapsExampleTheGoogleMapsJavaScriptAPIletsyouembedGoogleMapsinyour ownwebpages.Version3ofthisAPIisespeciallydesignedtobefaster andmoreapplicabletomobiledevices,aswellastraditionaldesktop browserapplications.[9]WiththisAPI,itiseasyforadevelopertoembedamap thatfunctionsjustlikethehttp://maps.google.com/ webpage,andtocustomizeitslookandfunctionalitytosuittheneedsof theapplicationbeingbuilt.ItisaverypopularAPIforbuildingweb applications,currentlybeingusedinover150,000websites.[10]TheGoogleMapsAPI,BrieflyForthepurposesofthisbook,Ihaveincludedallofthecodefor theGoogleMapsapplicationintoasingleHTMLfiletomakeiteasierto read.IfIweretocreateanactualapplication,Iwouldbreakthe CascadingStyleSheet(CSS)rulesandJavaScriptintotheirownfiles (perhapsmultiplefilesshouldtheapplicationbemorecomplex)asa betterprogrammingpractice.TakealookatthecodeinExample 4-1,which containseverythingneededtocreateasimpleGoogleMap application.Example 4-1. AsimpleGoogleMap ASimpleGoogleMap html{height:100%} body{height:100%;margin:0;padding:0} #map{height:100%} varmap; /*Thisiscalledoncethepagehasloaded*/ functionInitMap(){ /*Setalloftheoptionsforthemap*/ varoptions={ zoom:4, center:newgoogle.maps.LatLng(38.6201,-90.2003), mapTypeId:google.maps.MapTypeId.ROADMAP, mapTypeControl:true, mapTypeControlOptions:{ style:google.maps.MapTypeControlStyle.HORIZONTAL_BAR, position:google.maps.ControlPosition.BOTTOM_CENTER }, panControl:true, panControlOptions:{ position:google.maps.ControlPosition.TOP_RIGHT }, zoomControl:true, zoomControlOptions:{ style:google.maps.ZoomControlStyle.LARGE, position:google.maps.ControlPosition.LEFT_CENTER }, scaleControl:true, scaleControlOptions:{ position:google.maps.ControlPosition.BOTTOM_LEFT }, streetViewControl:true, streetViewControlOptions:{ position:google.maps.ControlPosition.LEFT_TOP } }; /*CreateanewMapfortheapplication*/ map=newgoogle.maps.Map(document.getElementById('map'),options); } /*Autilityobjectforsimpleeventhandlilng*/ varUtils={}; Utils.addEvent=(function(){ returnfunctionaddEvent(eventObj,event,eventHandler){ if(eventObj.addEventListener){ eventObj.addEventListener(event,eventHandler,false); }elseif(eventObj.attachEvent){ event='on'+event; eventObj.attachEvent(event,eventHandler); }else{ eventObj['on'+event]=function(){eventHandler()}; } }; }()); Utils.removeEvent=(function(){ returnfunctionremoveEvent(event){ if(event.preventDefault){ event.preventDefault(); event.stopProgagation(); }else{ event.returnValue=false; event.cancelBubble=true; } }; }()); Utils.addEvent(window,'load',InitMap);

ThecodeinExample 4-1producesamaplike thatshowninFigure 4-1.Iwillstepthrough thiscodeinmoredetailinamoment,butthereareseveralthingsthat shouldbenotedrightaway:TheapplicationiswritteninHTML5.TheGoogleMapsJavaScriptAPIisincludedintheapplication bycallingitfromGoogle’ssite.ThereareacoupleofutilityJavaScriptfunctionsthataidin cross-browsercomplianteventhandling.AGoogleMapiscreatedbyspecifyingthecontainer,a

element,toholdthe map,andasetofoptionsthatallowthedevelopertocustomizethe lookofthemap’scontrols.Figure 4-1. AsimpleGoogleMapinChromeSpecifyingaDOCTYPEinthe applicationguaranteesthatbrowserswillrenderinstandards-compliantmode,makingitmore cross-browserfriendly.IchoseHTML5asitwillsoonbetheindustry standard,butanytrueDOCTYPEmaybe used.TheGoogleMapsJavaScriptAPIisincludedintheapplicationwith thefollowingline:ThismakesthelatestversionoftheAPIavailableforthe application.Theparametersensoris settofalsetoindicatethatthemapisnotusing asensortodeterminetheuser’slocation.NoteWhengeolocationisaddedtoExample 4-1, thevalueofthesensorparameter willbechangedtotruesothattheAPIknows thatalocationwillbegatheredbya“sensor,”liketheGPSlocator inaphone.Lastly,beforelookingattheGoogleMapJavaScriptAPIspecific code,theelement specifyingaviewportisrecognized onlybytheiPhonerightnow,andtellsittosettheapplicationto full-screenandnotallowtheusertoresizetheapplication.Other smartphonesmaytakeadvantageofthiselementinthefuture.TheUtilsvariableisnothing morethananobjectthatholdscross-browsereventhandlingfunctions thatareusedtocreateamoreflexibleapplication.Byusingthe Utils.addEvent()method,thiscode canbepluggedintoanexistingapplicationandthedeveloperdoesnot havetoworryaboutoverwritinganexistingonloadfunctionthatmayalreadybepresent. IfaJavaScriptlibrarylikejQueryorDojoisbeingusedinthe application,thenitwillmostlikelyhavebuilt-inmethodsthatalso takethehassleoutofcross-browsereventhandling.AMapiscreatedbyinstantiatinganew google.maps.Mapobjectandspecifying theelementthatwillcontainthemap.Theelementisreferencedusing thedocument.getElementById()DOM method.TheMapobjectalsotakesan optionsobjectthatcontrolseverythingelseabout themap.MapOptionsBydefault,theGoogleMapsJavaScriptAPIprovidescontrols thatenablebasicmapnavigationandtypeswitching.Inaddition,all deviceshavekeyboardhandlingonbydefault.Thedefaultcontrolscan bedisabledusingtheMap’sdisableDefaultUIproperty,andindividual controlscanbemanipulatedusingtheircorresponding properties.InExample 4-1,thefollowingcontrolswere configuredforthemap:zoomThedefaultzoomlevelwassetto 4intheexample.Thezoomproperty canrangefrom0to 21+,where 0isaviewofthewholeworld,and 21isdowntoindividual buildings.centerDefinesthecenterofthemapbyapairof coordinates.mapTypeTheGoogleMapsJavaScriptAPImakesthefollowingmap typesavailable:ROADMAP, SATELLITE,HYBRID,andTERRAIN.mapTypeControl,panControl,zoomControl,scaleControl, streetViewControlThesecontrolsaretoggledonoroffwithvaluesof trueandfalse.In addition,eachhasspecificconfigurationoptionsalongwitha positionproperty.Formoreinformationonoptionsavailableforthe Mapobject,visittheGoogleMapsJavaScriptAPI V3Developer’s GuideandAPI Reference.AddingGeolocationtoGoogleMapsAswesawinChapter 3,thereare threemaincomponentsneededinordertoaddgeolocationtotheGoogle mapinExample 4-1:acalltogetCurrentPosition(),a successCallbackfunctiontodosomethingwiththe positionwhenwegetit,andanerrorCallback functionincasesomethinggoeswrong.Wewillcreateafunctioncalled getLocation()tohandlecheckingfor thenavigator.geolocationobjectand formakingourinitialcallforalocation.Thisfunctionwilltake advantageofaglobalvariablecalledbrowserSupportthatwilleventuallyletour errorCallbackfunctionknowiftheerrorisfrom theAPIoralackofbrowsersupport.Iamdoingthissothatallofour errorhandlingisinonefunctioninsteadofhavingerroralertsspread throughoutthecode.Thisway,ifIchoosetodosomethingmorerobust withmyerrorhandlingotherthansimplyalerttheusertoaproblem, alloftheerrorcodeisinoneplace.Example 4-2illustratesthisnew functionalityimplementedintoourGoogleMapexample.Notethatchanges andadditionstothecodearehighlightedinboldforeasier identification.Example 4-2. AddinggeolocationtoaGoogleMap AddingGeolocationtoaGoogleMap html{height:100%}– body{height:100%;margin:0;padding:0} #map{height:100%} varmap; varbrowserSupport=false; varattempts=0; /*Thisiscalledoncethepagehasloaded*/ functionInitMap(){ /*Setalloftheoptionsforthemap*/ varoptions={ zoom:4, center:newgoogle.maps.LatLng(38.6201,-90.2003), mapTypeId:google.maps.MapTypeId.ROADMAP, mapTypeControl:true, mapTypeControlOptions:{ style:google.maps.MapTypeControlStyle.HORIZONTAL_BAR, position:google.maps.ControlPosition.BOTTOM_CENTER }, panControl:true, panControlOptions:{ position:google.maps.ControlPosition.TOP_RIGHT }, zoomControl:true, zoomControlOptions:{ style:google.maps.ZoomControlStyle.LARGE, position:google.maps.ControlPosition.LEFT_CENTER }, scaleControl:true, scaleControlOptions:{ position:google.maps.ControlPosition.BOTTOM_LEFT }, streetViewControl:true, streetViewControlOptions:{ position:google.maps.ControlPosition.LEFT_TOP } }; /*CreateanewMapfortheapplication*/ map=newgoogle.maps.Map(document.getElementById('map'),options); /*AddGeolocation*/ getLocation(); } /* *IftheW3CGeolocationobjectisavailablethengetthecurrent *location,otherwisereporttheproblem */ functiongetLocation(){ /*CheckifthebrowsersupportstheW3CGeolocationAPI*/ if(navigator.geolocation){ browserSupport=true; navigator.geolocation.getCurrentPosition(plotLocation, reportProblem,{timeout:45000}); }else reportProblem(); } /*Plotthelocationonthemapandzoomtoit*/ functionplotLocation(position){ attempts=0; varpoint=newgoogle.maps.LatLng(position.coords.latitude, position.coords.longitude); varmarker=newgoogle.maps.Marker({ position:point }); marker.setMap(map); map.setCenter(point); map.setZoom(15); } /*Reportanyerrorsusingthisfunction*/ functionreportProblem(e){ /*IsthisasupportissueoranAPIissue?*/ if(browserSupport){ switch(e.code){ casee.PERMISSION_DENIED: alert('Youhavedeniedaccesstoyourposition.Youwill'+ 'notgetthemostoutoftheapplicationnow.'); break; casee.POSITION_UNAVAILABLE: alert('Therewasaproblemgettingyourposition.'); break; casee.TIMEOUT: /*Threechangestogetthelocationbeforeatruetimeout*/ if(++attempts<3){ navigator.geolocation.getCurrentPosition(plotLocation, reportProblem); }else alert('Theapplicationhastimedoutattemptingtoget'+ 'yourlocation.'); break; default: alert('TherewasahorribleGeolocationerrorthathas'+ 'notbeendefined.'); } }else alert('Geolocationisnotsupportedbyyourbrowser.'); } /*Autilityobjectforsimpleeventhandlilng*/ varUtils={}; Utils.addEvent=(function(){ returnfunctionaddEvent(eventObj,event,eventHandler){ if(eventObj.addEventListener){ eventObj.addEventListener(event,eventHandler,false); }elseif(eventObj.attachEvent){ event='on'+event; eventObj.attachEvent(event,eventHandler); }else{ eventObj['on'+event]=function(){eventHandler()}; } }; }()); Utils.removeEvent=(function(){ returnfunctionremoveEvent(event){ if(event.preventDefault){ event.preventDefault(); event.stopProgagation(); }else{ event.returnValue=false; event.cancelBubble=true; } }; }()); Utils.addEvent(window,'load',InitMap);

Thefirstthingtonoteinthisexampleisthatsensor=truewhenwemakethecalltothe GoogleJavaScriptAPI,sinceweareusinggeolocationinthisexample. ThegetLocation()functioniscalled rightafterourmapobjectisinstantiated.Next,wedefineourtwocallbackfunctions:plotLocation()andreportProblem().plotLocation()willbepasseda Positionobjectthatwillcontainallofthe geolocationinformation,whilereportProblem()willbepasseda PositionErrorobjectthatwillcontainanerror codeandmessage.TheplotLocation()function createsaLatLngobjectbasedonthepassed latitudeandlongitudeofthePositionobject,and fromthatLatLngobjecta Markerobjectiscreated.The Markerisplacedonthemap,andthenthemapis centeredandzoomedtothecurrentgeolocation.ThereportProblem()function, meanwhile,simplyalertstheusertothespecificerrortheapplication has,basedeitheronthebrowserSupportvariable,orthe PositionErrorcodethatispassedtothefunction. Iftheerrorisatimeout,theapplicationwillmakethreeattemptsat gettingthecurrentpositionoftheuserbeforegivingupandreporting aproblem.AddingGeolocationforOtherBrowsersThecodeinExample 4-2worksfor browsersthatsupporttheW3CGeolocationAPI,butwhataboutbrowsers thatdonot?RememberbackinChapter 1whenI discussedotherbrowsersolutions,andinparticulargeo-location-javascript?Thereareseverelimitationstothe geolocationfunctionalitythatthisJavaScriptlibrarygives,butit isonesolutionthatattemptscross-browsercompatibility.OurGoogle Mapsexampleissimpleenoughthatwecanusethislibraryandnot worrytoomuchaboutthelackoffunctionality.Example 4-3showsimplementingacross-browser geolocationsolutionusingthegeo-location-javascriptlibrary.Again, changesandadditionstothecodearehighlightedinboldforeasier identification.Example 4-3. AddinggeolocationforotherbrowserstoaGoogleMap AddingGeolocationforOtherBrowserstoaGoogleMap html{height:100%} body{height:100%;margin:0;padding:0} #map{height:100%} varmap; varbrowserSupport=false; /*Thisiscalledoncethepagehasloaded*/ functionInitMap(){ /*Setalloftheoptionsforthemap*/ varoptions={ zoom:4, center:newgoogle.maps.LatLng(38.6201,-90.2003), mapTypeId:google.maps.MapTypeId.ROADMAP, mapTypeControl:true, mapTypeControlOptions:{ style:google.maps.MapTypeControlStyle.HORIZONTAL_BAR, position:google.maps.ControlPosition.BOTTOM_CENTER }, panControl:true, panControlOptions:{ position:google.maps.ControlPosition.TOP_RIGHT }, zoomControl:true, zoomControlOptions:{ style:google.maps.ZoomControlStyle.LARGE, position:google.maps.ControlPosition.LEFT_CENTER }, scaleControl:true, scaleControlOptions:{ position:google.maps.ControlPosition.BOTTOM_LEFT }, streetViewControl:true, streetViewControlOptions:{ position:google.maps.ControlPosition.LEFT_TOP } }; /*CreateanewMapfortheapplication*/ map=newgoogle.maps.Map(document.getElementById('map'),options); /*AddGeolocation*/ getLocation(); } /* *ThebrowserwillnowusewhatevergeolocationAPIisavailableto *it;hopefullyitwillbetheW3CGeolocationobjectthatisusedto *getthecurrentlocation.Ifthereisnogeolocationsupportatall, *thenreporttheproblem. */ functiongetLocation(){ /*CheckifthebrowsersupportsanygeolocationAPI*/ if(geo_position_js.init()){ browserSupport=true; geo_position_js.getCurrentPosition(plotLocation, reportProblem); }else reportProblem(); } /*Plotthelocationonthemapandzoomtoit*/ functionplotLocation(position){ varpoint=newgoogle.maps.LatLng(position.coords.latitude, position.coords.longitude); varmarker=newgoogle.maps.Marker({ position:point }); marker.setMap(map); map.setCenter(point); map.setZoom(15); } /*Reportanyerrorsusingthisfunction*/ functionreportProblem(){ /*IsthisasupportissueoranAPIissue?*/ if(browserSupport) alert('Couldnotlocateyourdevice.'); else alert('Geolocationisnotsupportedbyyourbrowser.'); } /*Autilityobjectforsimpleeventhandlilng*/ varUtils={}; Utils.addEvent=(function(){ returnfunctionaddEvent(eventObj,event,eventHandler){ if(eventObj.addEventListener){ eventObj.addEventListener(event,eventHandler,false); }elseif(eventObj.attachEvent){ event='on'+event; eventObj.attachEvent(event,eventHandler); }else{ eventObj['on'+event]=function(){eventHandler()}; } }; }()); Utils.removeEvent=(function(){ returnfunctionremoveEvent(event){ if(event.preventDefault){ event.preventDefault(); event.stopProgagation(); }else{ event.returnValue=false; event.cancelBubble=true; } }; }()); Utils.addEvent(window,'load',InitMap);

Callstogears_init.jsand geo.jsloadthelibrariesweare usingforgeolocationinthisexample.Allofthe MapfunctionalityremainsthesameasinExample 4-2.Insteadofcheckingfornavigation.geolocation,inthisexample,the geo-location-javascriptAPIisinitializedandwillreturnwhetheror notthebrowsersupportsanyofthegeolocationAPIsthat geo-location-javascriptdoes.AsimplercalltogetCurrentPosition()ismade,withoutthe timeoutset,butotherwisethegetLocation()functionisverysimilarto thissamefunctioninExample 4-2.Nothingchangedbetweenthetwogeolocationexamplesinthe plotLocation()function,however therearebigchangesinthereportProblem()function.First,notethat thereisnoPositionErrorobjectpassedtothe function—geo-location-javascriptdoesnothavethisfunctionality.The errorhandlingisverysimplistic,andthisisoneofthebiggest drawbacksofthisAPI.AsIsaidearlier,thisworksadequately becauseweareusingasimpleexample.However,shouldthegeolocation needsbemorecomplex,alotofadditionalcodingwillbeneededto gettheapplicationworkingcorrectly.AnArcGISJavaScriptAPIExampleEsri’sArcGISAPIforJavaScriptallowsthedevelopertotake advantageofallthemapping,editing,geocoding,andgeoprocessing servicesthatEsrioffers.WiththisAPI,adeveloperisabletoembeda mapthatfunctions,likethoseonhttp://www.arcgis.com/,andtocustomizeitslookand functionalitytosatisfytheneedsoftheapplicationbeingbuilt.The JavaScriptAPIishostedonArcGISOnlineandisfreelyavailableforuse. ManysitesusethisAPIfortheirGISneeds,especiallywhentheirdesktop andserverGISneedsaremetusingEsrienterprisesoftware.Atthetime ofthiswriting,thecurrentversionoftheAPIis2.2.TheArcGISJavaScriptAPI,BrieflyAgain,forthisbook,Ihaveincludedallofthecodeforthe ArcGISJavaScriptMapapplicationintoasingleHTMLfiletomakeit easiertoread.Inaproductionapplication,IwouldbreaktheCSSand JavaScriptintotheirownfiles.TakealookatthecodeinExample 4-4,which containseverythingneededtocreateasimpleArcGISJavaScriptMap application.Example 4-4. AsimpleEsriArcGISMap

ASimpleEsriArcGISMap html,body{ height:100%; margin:0; padding:0; width:100%; } #map{ height:100%; width:100%; } vardjConfig={parseOnLoad:true}; dojo.require('esri.map'); varmap; varinitialExtent={ xmin:-119.3324, ymin:26.3156, xmax:-72.3568, ymax:55.0558, /* *WebMercator(102113),orWGS84(4326)-thesearethe *onlytwothatsupportcontinuouspanacrossthedateline */ spatialReference:{wkid:4326} }; varstartExtent; varbasemap; functioninitApp(){ varstartExtent=newesri.geometry.Extent(initialExtent); map=newesri.Map('map',{ extent:startExtent, wrapAround180:true }); basemap=newesri.layers.ArcGISTiledMapServiceLayer( 'http://server.arcgisonline.com/ArcGIS/rest/services/'+ 'ESRI_StreetMap_World_2D/MapServer'); map.addLayer(basemap); } dojo.addOnLoad(initApp);

ThecodeinExample 4-4producesamaplike thatshowninFigure 4-2.Iwillstepthroughthis codeinmoredetailinamoment,butthereareseveralthingsthat shouldbenotedrightaway:TheapplicationiswritteninHTML5.TheEsriArcGISAPIforJavaScriptisincludedinthe applicationbycallingitfromArcGISOnline.TheDojoToolkit, withitsimmensefunctionality,isalsoincludedintheAPIcallto ArcGISOnline.AnArcGISJavaScriptMapiscreatedbyspecifyingthe container,a

element, toholdthemap,andasetofinlineoptionsthatdefineaspectsof themapbeingcreated.AswiththeGoogleMapexamples,Ichosetowritethisapplication inHTML5,asitwillsoonbetheindustrystandard.Plusthiswillgive itadditionalfunctionalityforcreatingmoreimpressivemapsinthe future.AnytrueDOCTYPEmay,of course,beusedandtheapplicationwillrunfine.Figure 4-2. AsimpleEsriArcGISMapinChromeTheEsriArcGISJavaScriptAPIandDojoToolkitareincludedin theapplicationwiththefollowingline: TheversionoftheAPIyouwishtouseisspecifiedinthe querystringoftheAPIcall,inthiscasethe latestversion:2.2.Onceagain,Iamusingaelementtospecifytheviewport,tellingittosettheapplicationto full-screenandnotallowtheusertoresizetheapplication—thisisan iPhonerecognizableelement.Thereisasecondelement,however,thatisused forInternetExplorerbrowsers,tellingthemtointerpretanddisplay theapplicationasInternetExplorer7would.Thiselementshouldchange asusageoftheIE7browserfinallydisappears.AMapiscreatedbyinstantiatinganew esri.Mapobjectandspecifyingthe elementthatwillcontainthemap.Theelementisreferencedbyits idvalue.The Mapobjectalsoacceptsan“options”objectthat controlsinitialextentandothermapvalues.Forexample,thewrapAround180property,whichisnewtothe 2.2API,tellsthemapwhetherornottocontinuouslypanacrossthe dateline.InallpreviousversionsoftheJavaScriptAPI,themapwould notscrollacrossthedatelinelikeotherweb-mappingapplications do.Formoreinformationonoptionsavailableforthe Mapobject,orAPIdetailsingeneral,visitthe ArcGIS APIforJavaScriptResourcepage.AddingGeolocationtoEsriMapsYouprobablynoticedthesimilaritiesbetweenthemapapplications inExample 4-1andExample 4-4 or,morespecifically,thewayinwhichamapwascreatedwitheachAPI. Whiletheapplicationsthemselvesarefairlysimilar,theway geolocationisaddedtobothofthemisnearlyidentical.ToaddW3C GeolocationAPIcodetotheArcGISJavaScriptapplication,weaddthe samebasiccodethatwedidfortheGoogleMap.First,wewillcreateafunctiongetLocation()tohandlecheckingforthe navigator.geolocationobjectandfor makingthecalltogetCurrentPosition().Thisfunctionwillonce againtakeadvantageofaglobalvariablecalledbrowserSupportthatwilleventuallyletour errorCallBackfunctionknowiftheerrorisfrom theAPIoralackofbrowsersupport.Example 4-5showsthegeolocationfunctionalityadded toourEsriArcGISMapexample.Changesandadditionstotheoriginal codearehighlightedinbold.Example 4-5. AddinggeolocationtoanEsriArcGISMap AddingGeolocationtoanEsriArcGISMap html,body{ height:100%; margin:0; padding:0; width:100%; } #map{ height:100%; width:100%; } vardjConfig={parseOnLoad:true}; dojo.require('esri.map'); varmap; varinitialExtent={ xmin:-119.3324, ymin:26.3156, xmax:-72.3568, ymax:55.0558, /* *WebMercator(102113),orWGS84(4326)-thesearethe *onlytwothatsupportcontinuouspanacrossthedateline */ spatialReference:{wkid:4326} }; varstartExtent; varbasemap; varbrowserSupport=false; varattempts=0; functioninitApp(){ varstartExtent=newesri.geometry.Extent(initialExtent); map=newesri.Map('map',{ extent:startExtent, wrapAround180:true }); basemap=newesri.layers.ArcGISTiledMapServiceLayer( 'http://server.arcgisonline.com/ArcGIS/rest/services/'+ 'ESRI_StreetMap_World_2D/MapServer'); map.addLayer(basemap); /*AddGeolocation*/ dojo.connect(map,'onLoad',function(){ getLocation(); }); } /* *IftheW3CGeolocationobjectisavailablethengetthecurrent *location,otherwisereporttheproblem */ functiongetLocation(){ /*CheckifthebrowsersupportstheW3CGeolocationAPI*/ if(navigator.geolocation){ browserSupport=true; navigator.geolocation.getCurrentPosition(plotLocation, reportProblem,{timeout:45000}); }else reportProblem(); } /*Plotthelocationonthemapandzoomtoit*/ functionplotLocation(position){ attempts=0; varpointsLayer=newesri.layers.GraphicsLayer(); map.addLayer(pointsLayer); varpoint=newesri.geometry.Point(position.coords.longitude, position.coords.latitude,newesri.SpatialReference({ wkid:4326 })); pointsLayer.add( newesri.Graphic( point, newesri.symbol.SimpleMarkerSymbol().setColor( newdojo.Color([255,0,0,0.5])) ) ); map.centerAndZoom(point,13); } /*Reportanyerrorsusingthisfunction*/ functionreportProblem(e){ /*IsthisasupportissueoranAPIissue?*/ if(browserSupport){ switch(e.code){ casee.PERMISSION_DENIED: alert('Youhavedeniedaccesstoyourposition.Youwill'+ 'notgetthemostoutoftheapplicationnow.'); break; casee.POSITION_UNAVAILABLE: alert('Therewasaproblemgettingyourposition.'); break; casee.TIMEOUT: /*Threechangestogetthelocationbeforeatruetimeout*/ if(++attempts<3){ navigator.geolocation.getCurrentPosition(plotLocation, reportProblem); }else alert('Theapplicationhastimedoutattemptingtoget'+ 'yourlocation.'); break; default: alert('TherewasahorribleGeolocationerrorthathas'+ 'notbeendefined.'); } }else alert('Geolocationisnotsupportedbyyourbrowser.'); } dojo.addOnLoad(initApp);

Inthisexample,thecalltothegetLocation()functionisinsideananonymous functionthatwillbecalledonanonLoadeventfromthe Map.Next,wedefineourtwocallbackfunctions: plotLocation()andreportProblem().ThereportProblem()functionisexactlylikeitscounterpartinExample 4-2,sothereisnoneedtogointoit again.plotLocation(),however,ismuchchanged asdifferentAPIshandleaddingpointsdifferently.TheplotLocation()function firstcreatesanesri.layers.GraphicsLayercalledpointsLayer,whichiswherethenewpointwill beplaced,andaddsthislayertothemap.Itthencreatesanew esri.geometry.Point,point,withthecoordinatespassedfromthe Positionobject.Next,itaddsanewgraphiconthe pointsLayerlayer,atpoint,withanesri.symbol.SimpleMarkerSymbol.Finally,the mapiscenteredandzoomedtothecurrentgeolocation.SupportforOtherBrowsersThecodeinExample 4-5willprovide geolocationsupportforbrowsersthatimplementtheW3CGeolocation API.Onceagain,weneedtorewriteourcodetoutilizethe geo-location-javascriptlibrarytogiveuscross-browsersupportfor ourgeolocationapplication. Example 4-6showsanimplementationofa cross-browsergeolocationapplicationusinggeo-location-javascript withintheEsriArcGISJavaScriptAPI.Ihaveagainhighlightedthe changesinthecodeinboldsotheyareeasiertosee.Example 4-6. AddinggeolocationforotherbrowserstoanEsriArcGIS Map

AddingGeolocationforOtherBrowserstoanEsriMap html,body{ height:100%; margin:0; padding:0; width:100%; } #map{ height:100%; width:100%; } vardjConfig={parseOnLoad:true}; dojo.require('esri.map'); varmap; varinitialExtent={ xmin:-119.3324, ymin:26.3156, xmax:-72.3568, ymax:55.0558, /* *WebMercator(102113),orWGS84(4326)-thesearethe *onlytwothatsupportcontinuouspanacrossthedateline */ spatialReference:{wkid:4326} }; varstartExtent; varbasemap; varbrowserSupport=false; functioninitApp(){ varstartExtent=newesri.geometry.Extent(initialExtent); map=newesri.Map('map',{ extent:startExtent, wrapAround180:true }); basemap=newesri.layers.ArcGISTiledMapServiceLayer( 'http://server.arcgisonline.com/ArcGIS/rest/services/'+ 'ESRI_StreetMap_World_2D/MapServer'); map.addLayer(basemap); /*AddGeolocation*/ dojo.connect(map,'onLoad',function(){ getLocation(); }); } /* *ThebrowserwillnowusewhatevergeolocationAPIisavailableto *it;hopefullyitwillbetheW3CGeolocationobjectthatisusedto *getthecurrentlocation.Ifthereisnogeolocationsupportatall, *thenreporttheproblem. */ functiongetLocation(){ /*CheckifthebrowsersupportsanygeolocationAPI*/ if(geo_position_js.init()){ browserSupport=true; geo_position_js.getCurrentPosition(plotLocation, reportProblem); }else reportProblem(); } /*Plotthelocationonthemapandzoomtoit*/ functionplotLocation(position){ attempts=0; varpointsLayer=newesri.layers.GraphicsLayer(); map.addLayer(pointsLayer); varpoint=newesri.geometry.Point(position.coords.longitude, position.coords.latitude,newesri.SpatialReference({ wkid:4326 })); pointsLayer.add( newesri.Graphic( point, newesri.symbol.SimpleMarkerSymbol().setColor( newdojo.Color([255,0,0,0.5])) ) ); map.centerAndZoom(point,13); } /*Reportanyerrorsusingthisfunction*/ functionreportProblem(){ /*IsthisasupportissueoranAPIissue?*/ if(browserSupport) alert('Couldnotlocateyourdevice.'); else alert('Geolocationisnotsupportedbyyourbrowser.'); } dojo.addOnLoad(initApp);

Callstogears_init.jsand geo.jsloadthelibrariesweare usingforgeolocationinthisexample.TheMap functionalityitselfremainsthesameasinExample 4-5.Insteadofcheckingfornavigator.geolocation,the geo-location-javascriptinit() functioniscalled,whichreturnswhetherornotthebrowsersupports anygeolocationAPI.AsimplercalltogetCurrentPosition()ismade,withoutthe timeoutset,butotherwisethegetLocation()functionisverysimilarto thissamefunctioninExample 4-5.NothingchangedbetweenthetwoEsrigeolocationexamplesinthe plotLocation()function,butthere are,obviously,bigchangesinthereportProblem()functionbecauseofthelack ofaPositionErrorobjectwith geo-location-javascript.ThisiswhatwesawbackinExample 4-3.Formorecomplicatedcross-browsergeolocationneeds,additional andmorecomplexcodingwillberequiredtogetthejobdone. Hopefullythegeo-location-javascriptlibrarywilleventuallyaddmore functionalitytoitscodebasesothatitbettermirrorstheW3C GeolocationAPImethodsandproperties.Untilthatday,itisupto applicationdeveloperstowritethisfunctionalitythemselves.Itis eitherthat,oreveryoneneedstostopusingoutdatedlegacybrowsers andphones—butunfortunatelyIdonotseethathappeningforafew yearsstill.[9]GoogleMapsJavaScriptAPIV3.http://code.google.com/apis/maps/documentation/javascript/.[10]MappingSuccess:GoogleMapsCaseStudies. http://maps.google.com/help/maps/casestudies/. GetHTML5GeolocationnowwiththeO’Reillylearningplatform. O’Reillymembersexperienceliveonlinetraining,plusbooks,videos,anddigitalcontentfromnearly200publishers. Startyourfreetrial Don’tleaveempty-handed GetMarkRichards’sSoftwareArchitecturePatternsebooktobetterunderstandhowtodesigncomponents—andhowtheyshouldinteract. It’syours,free. Getitnow Close



請為這篇文章評分?