{"id":170141,"date":"2013-02-20T20:43:05","date_gmt":"2013-02-20T16:43:05","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=170141"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=170141","title":{"rendered":"<span class=\"post_title\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Google Map \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0430 JavaFX<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t<img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/120\/b8b\/656\/120b8b6569dc29022858125ee0ba4120.png\"\/><br \/>  \u0425\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0441\u0432\u043e\u0435\u043c \u043e\u043f\u044b\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Google Maps \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0430 JavaFX. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043a\u0430\u0440\u0442\u044b \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0432\u044b\u0437\u043e\u0432 Google Maps JavaScript API v3 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u044b \u0438\u0437 \u0441\u0432\u043e\u0435\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 Java.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h4>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h4>\n<p>  \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0430\u0440\u0442\u044b \u043d\u0430 javascript, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0444\u043e\u0440\u043c\u0438\u043c \u0432\u0432\u0438\u0434\u0435 html-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b map.html. \u0414\u0430\u043b\u0435\u0435 \u043f\u043e \u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">map.html<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"html\">&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt;     &lt;meta name=&quot;viewport&quot; content=&quot;initial-scale=1.0, user-scalable=no&quot; \/&gt;     &lt;style type=&quot;text\/css&quot;&gt;         html { height: 100% }         body { height: 100%; margin: 0; padding: 0 }         #map_canvas { height: 100% }     &lt;\/style&gt;     &lt;script type=&quot;text\/javascript&quot;             src=&quot;https:\/\/maps.googleapis.com\/maps\/api\/js?key=***&sensor=false&quot;&gt;     &lt;\/script&gt;     &lt;script type=&quot;text\/javascript&quot;&gt;         var map;         var marker;          function initialize() {             var defLatLng = new google.maps.LatLng(59.95632093391832, 30.309906005859375);             var mapOptions = {                 center: defLatLng,                 zoom: 3,                 mapTypeId: google.maps.MapTypeId.ROADMAP,                 disableDefaultUI: true,                 panControl: false             };             map = new google.maps.Map(document.getElementById(&quot;map_canvas&quot;), mapOptions);              marker = new google.maps.Marker({                 position: defLatLng,                 map: map,                 icon: &quot;img\/Pin.png&quot;             });         }     &lt;\/script&gt; &lt;\/head&gt; &lt;body onload=&quot;initialize()&quot;&gt; &lt;div id=&quot;map_canvas&quot; style=&quot;width:100%; height:100%&quot;&gt;&lt;\/div&gt; &lt;\/body&gt; &lt;\/html&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c html-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 \u043a\u0430\u0440\u0442\u043e\u0439. \u0415\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435. \u0412 JavaFX \u0435\u0441\u0442\u044c \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u0435\u0431-\u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430: javafx.scene.web.WebView. \u0412\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0438\u043c \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 html-\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0438. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043b\u0430\u0441\u0441 GoogleMap, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c Google Map \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0430 JavaFX. \u0427\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043a\u0430\u0440\u0442\u043e\u0439 \u043a\u0430\u043a \u0441 \u043b\u044e\u0431\u044b\u043c \u0434\u0440\u0443\u0433\u0438\u043c JavaFX-\u043d\u043e\u0434\u043e\u043c (Scene graph node), \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u043c\u0441\u044f \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 javafx.scene.Parent.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">GoogleMap.java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">public class GoogleMap extends Parent {      public GoogleMap() {         initMap();         getChildren().add(webView);     }      private void initMap()     {         webView = new WebView();         webEngine = webView.getEngine();         webEngine.load(getClass().getResource(&quot;map.html&quot;).toExternalForm());         ready = false;         webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener&lt;Worker.State&gt;()         {             @Override             public void changed(final ObservableValue&lt;? extends Worker.State&gt; observableValue,                                 final Worker.State oldState,                                 final Worker.State newState)             {                 if (newState == Worker.State.SUCCEEDED)                 {                     ready = true;                 }             }         });     }      private WebView webView;     private WebEngine webEngine;     private boolean ready; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u0440\u0442\u044b \u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u041d\u0430\u043c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0430\u0440\u0442\u043e\u0439 \u0438 \u043e\u0442\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043a\u0430\u0440\u0442\u044b. \u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c \u043d\u0430 javascript \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 netscape.javascript.JSObject, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 initCommunication(), \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u043c \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 GoogleMap. \u0422\u0430\u043a \u0436\u0435 \u0432 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u0437\u0430\u043a\u0438\u043d\u0435\u043c \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 javascript \u043a\u043e\u0434\u0430 GoogleMap.this (\u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 GoogleMap), \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043b\u0430\u0441\u0441\u0430 GoogleMap \u0438\u0437 \u043a\u043e\u0434\u0430 \u043d\u0430 javascript.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">initCommunication()<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">    private void initCommunication() {         webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener&lt;Worker.State&gt;()         {             @Override             public void changed(final ObservableValue&lt;? extends Worker.State&gt; observableValue,                                 final Worker.State oldState,                                 final Worker.State newState)             {                 if (newState == Worker.State.SUCCEEDED)                 {                     doc = (JSObject) webEngine.executeScript(&quot;window&quot;);                     doc.setMember(&quot;app&quot;, GoogleMap.this);                 }             }         });     }       private JSObject doc; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0432\u044b\u0437\u043e\u0432 Java \u043a\u043e\u0434\u0430 \u0438\u0437 javascript \u043a\u043e\u0434\u0430 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043e\u0442\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043a\u043b\u0438\u043a\u0430 \u043f\u043e \u043a\u0430\u0440\u0442\u0435. \u042d\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u043a\u0430\u043a \u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u0430\u0440\u0442\u0443 \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0433\u0435\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0430\u0436\u0430\u0442\u0438\u044f. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0441\u043e\u0431\u044b\u0442\u0438\u044f:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">MapEvent.java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">public class MapEvent extends Event {      public MapEvent(GoogleMap map, double lat, double lng) {         super(map, Event.NULL_SOURCE_TARGET, Event.ANY);         this.lat = lat;         this.lng = lng;     }      public double getLat() {         return this.lat;     }      public double getLng() {         return this.lng;     }      private double lat;     private double lng; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043b\u0430\u0441\u0441\u0430 GoogleMap, \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u043f\u0440\u0438\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0442 javasript \u043a\u043e\u0434\u0430 \u0438 \u0432\u044b\u0437\u043e\u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043b\u0430\u0441\u0441\u0430 GoogleMap<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">    public void setOnMapLatLngChanged(EventHandler&lt;MapEvent&gt; eventHandler) {         onMapLatLngChanged = eventHandler;     }      public void handle(double lat, double lng) {         if(onMapLatLngChanged != null) {             MapEvent event = new MapEvent(this, lat, lng);             onMapLatLngChanged.handle(event);         }     }     private EventHandler&lt;MapEvent&gt; onMapLatLngChanged; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043a\u0430\u0440\u0442\u044b \u0432 javascript \u043a\u043e\u0434\u0435 \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0432 \u043d\u0435\u043c \u043c\u0435\u0442\u043e\u0434 handle(double lat, double lng) \u043a\u043b\u0430\u0441\u0441\u0430 GoogleMap:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">get_click_position(event)<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">function get_click_position(event){             var location = event.latLng;             var lat = location.lat();             var lng = location.lng();             app.handle(lat, lng);  } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 GoogleMap \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 javascript \u0438\u0437 java \u043a\u043e\u0434\u0430:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">invokeJS(final String str)<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">    private void invokeJS(final String str) {         if(ready) {             doc.eval(str);         }         else {             webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener&lt;Worker.State&gt;()             {                 @Override                 public void changed(final ObservableValue&lt;? extends Worker.State&gt; observableValue,                                     final Worker.State oldState,                                     final Worker.State newState)                 {                     if (newState == Worker.State.SUCCEEDED)                     {                         doc.eval(str);                     }                 }             });         }     } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<h4>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/h4>\n<p>  \u041d\u0435 \u0431\u0443\u0434\u0443 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u044f\u0441\u043d\u044f\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0442\u0438\u043f\u0430 \u043a\u0430\u0440\u0442\u044b, \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0446\u0435\u043d\u0442\u0440\u0430 \u043a\u0430\u0440\u0442\u044b, \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u0443\u0440\u0441\u043e\u0440\u0430. \u0412\u0441\u0435 \u044d\u0442\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0435\u0441\u0442\u044c \u0432 \u043f\u043e\u043b\u043d\u044b\u0445 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">GoogleMap.java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">public class GoogleMap extends Parent {      public GoogleMap() {         initMap();         initCommunication();         getChildren().add(webView);         setMarkerPosition(0,0);         setMapCenter(0, 0);         switchTerrain(); }      private void initMap()     {         webView = new WebView();         webEngine = webView.getEngine();         webEngine.load(getClass().getResource(&quot;resources\/map.html&quot;).toExternalForm());         ready = false;         webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener&lt;Worker.State&gt;()         {             @Override             public void changed(final ObservableValue&lt;? extends Worker.State&gt; observableValue,                                 final Worker.State oldState,                                 final Worker.State newState)             {                 if (newState == Worker.State.SUCCEEDED)                 {                     ready = true;                 }             }         });     }      private void initCommunication() {         webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener&lt;Worker.State&gt;()         {             @Override             public void changed(final ObservableValue&lt;? extends Worker.State&gt; observableValue,                                 final Worker.State oldState,                                 final Worker.State newState)             {                 if (newState == Worker.State.SUCCEEDED)                 {                     doc = (JSObject) webEngine.executeScript(&quot;window&quot;);                     doc.setMember(&quot;app&quot;, GoogleMap.this);                 }             }         });     }      private void invokeJS(final String str) {         if(ready) {             doc.eval(str);         }         else {             webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener&lt;Worker.State&gt;()             {                 @Override                 public void changed(final ObservableValue&lt;? extends Worker.State&gt; observableValue,                                     final Worker.State oldState,                                     final Worker.State newState)                 {                     if (newState == Worker.State.SUCCEEDED)                     {                         doc.eval(str);                     }                 }             });         }     }      public void setOnMapLatLngChanged(EventHandler&lt;MapEvent&gt; eventHandler) {         onMapLatLngChanged = eventHandler;     }      public void handle(double lat, double lng) {         if(onMapLatLngChanged != null) {             MapEvent event = new MapEvent(this, lat, lng);             onMapLatLngChanged.handle(event);         }     }      public void setMarkerPosition(double lat, double lng) {         String sLat = Double.toString(lat);         String sLng = Double.toString(lng);         invokeJS(&quot;setMarkerPosition(&quot; + sLat + &quot;, &quot; + sLng + &quot;)&quot;);     }      public void setMapCenter(double lat, double lng) {         String sLat = Double.toString(lat);         String sLng = Double.toString(lng);         invokeJS(&quot;setMapCenter(&quot; + sLat + &quot;, &quot; + sLng + &quot;)&quot;);     }      public void switchSatellite() {         invokeJS(&quot;switchSatellite()&quot;);     }      public void switchRoadmap() {         invokeJS(&quot;switchRoadmap()&quot;);     }      public void switchHybrid() {         invokeJS(&quot;switchHybrid()&quot;);     }      public void switchTerrain() {         invokeJS(&quot;switchTerrain()&quot;);     }      public void startJumping() {         invokeJS(&quot;startJumping()&quot;);     }      public void stopJumping() {         invokeJS(&quot;stopJumping()&quot;);     }      public void setHeight(double h) {         webView.setPrefHeight(h);     }      public void setWidth(double w) {         webView.setPrefWidth(w);     }      public ReadOnlyDoubleProperty widthProperty() {         return webView.widthProperty();     }      private JSObject doc;     private EventHandler&lt;MapEvent&gt; onMapLatLngChanged;     private WebView webView;     private WebEngine webEngine;     private boolean ready; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">map.html<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"html\">&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt;     &lt;meta name=&quot;viewport&quot; content=&quot;initial-scale=1.0, user-scalable=no&quot; \/&gt;     &lt;style type=&quot;text\/css&quot;&gt;         html { height: 100% }         body { height: 100%; margin: 0; padding: 0 }         #map_canvas { height: 100% }     &lt;\/style&gt;     &lt;script type=&quot;text\/javascript&quot;             src=&quot;https:\/\/maps.googleapis.com\/maps\/api\/js?key=***&sensor=false&quot;&gt;     &lt;\/script&gt;     &lt;script type=&quot;text\/javascript&quot;&gt;         var map;         var marker;          function get_click_position(event){             var location = event.latLng;             var lat = location.lat();             var lng = location.lng();             setMarkerPosition(lat, lng);             app.handle(lat, lng);         }          function setMarkerPosition(lat, lng) {             var clickLatLng = new google.maps.LatLng(lat, lng);             marker.setPosition(clickLatLng);         }          function startJumping(){             marker.setAnimation(google.maps.Animation.BOUNCE);         }          function stopJumping(){             marker.setAnimation(google.maps.Animation.BOUNCE);         }          function setMapCenter(lat, lng) {             var latlng = new google.maps.LatLng(lat, lng);             map.setCenter(latlng);         }          function switchSatellite() {             var mapOptions = {                 mapTypeId: google.maps.MapTypeId.SATELLITE             };             map.setOptions(mapOptions);             setLightMarkerIcon();         }          function switchRoadmap() {             var mapOptions = {                 mapTypeId: google.maps.MapTypeId.ROADMAP             };             map.setOptions(mapOptions);             setDarkMarkerIcon();         }          function switchHybrid() {             var mapOptions = {                 mapTypeId: google.maps.MapTypeId.HYBRID             };             map.setOptions(mapOptions);             setLightMarkerIcon();         }          function switchTerrain() {             var mapOptions = {                 mapTypeId: google.maps.MapTypeId.TERRAIN             };             map.setOptions(mapOptions);             setDarkMarkerIcon();         }          function initialize() {             var defLatLng = new google.maps.LatLng(59.95632093391832, 30.309906005859375);             var mapOptions = {                 center: defLatLng,                 zoom: 3,                 mapTypeId: google.maps.MapTypeId.ROADMAP,                 disableDefaultUI: true,                 panControl: false             };             map = new google.maps.Map(document.getElementById(&quot;map_canvas&quot;), mapOptions);             google.maps.event.addListener(map, 'click', get_click_position);              marker = new google.maps.Marker({                 position: defLatLng,                 map: map,                 icon: &quot;img\/Pin.png&quot;             });              app.handle(0, 0);         }          function setDarkMarkerIcon() {             marker.setIcon(&quot;img\/Pin.png&quot;);         }          function setLightMarkerIcon() {             marker.setIcon(&quot;img\/Pin_s.png&quot;);         }      &lt;\/script&gt; &lt;\/head&gt; &lt;body onload=&quot;initialize()&quot;&gt; &lt;div id=&quot;map_canvas&quot; style=&quot;width:100%; height:100%&quot;&gt;&lt;\/div&gt; &lt;\/body&gt; &lt;\/html&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041a\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u043b \u0412\u043e\u043b\u044c\u0442\u0435\u0440:<br \/>  <i>\u00ab\u042f \u043c\u043e\u0433\u0443 \u0431\u044b\u0442\u044c \u043d\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u044b\u043c \u0441 \u0412\u0430\u0448\u0438\u043c \u043c\u043d\u0435\u043d\u0438\u0435\u043c, \u043d\u043e \u044f \u0433\u043e\u0442\u043e\u0432 \u043e\u0442\u0434\u0430\u0442\u044c \u0436\u0438\u0437\u043d\u044c \u0437\u0430 \u0412\u0430\u0448\u0435 \u043f\u0440\u0430\u0432\u043e \u0432\u044b\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e.\u00bb<\/i>    \t \t\t   \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/170141\/\"> http:\/\/habrahabr.ru\/post\/170141\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t<img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/120\/b8b\/656\/120b8b6569dc29022858125ee0ba4120.png\"\/><br \/>  \u0425\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0441\u0432\u043e\u0435\u043c \u043e\u043f\u044b\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Google Maps \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0430 JavaFX. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043a\u0430\u0440\u0442\u044b \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0432\u044b\u0437\u043e\u0432 Google Maps JavaScript API v3 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u044b \u0438\u0437 \u0441\u0432\u043e\u0435\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 Java.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-170141","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/170141","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=170141"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/170141\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=170141"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=170141"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=170141"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}