概述

由于项目需要用到地图,虽然isis的插件库里有个现成的地图实现,不过用的google地图,虽然google地图可以不用注册Appkey,但完全打不开。所以打算改成国产地图。

效果

先看下运行效果。

列表中的效果:

整体效果:

详细效果:

实现思路

高德地图的API跟Google地图类似,编程模型也相同,甚至很多类的命名都一样的。所以,从Google迁到高德还是比较容易的。

高德跟Google一样,用一个DIV来渲染地图。根据Vicket的编程方式,这个Div使用一个组件来表示,这个组件包含了相应的属性和呈现出来的模板及脚本。

先看下Google的模板,很简单在Panel里放了一个Div:

<html xmlns:wicket>
<body>
<wicket:panel>
<div wicket:id="map" style="width:100%; height:100%"></div>
</wicket:panel>
</body>
</html>

 Google的客户端对应的初始化脚本:

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Wicket GMap3
*
* @author Tilman M�ller
* @author Joachim F. Rohde
*/
// Wicket Namespace
if (typeof(Wicket) === 'undefined') {
window.Wicket = {};
}
else if (typeof(Wicket) !== "object") {
throw new Error("Wicket already exists but is not an object");
} function WicketClientGeocoder() { try {
this.coder = new google.maps.Geocoder();
} catch (e) {
if( !Wicket.maps['_failSilently'] ) {
throw e;
}
} this.getLatLng = function(callBack, addressId){ var address = Wicket.$(addressId).value; this.coder.geocode({
'address': address
}, function(results, status){ if (status === google.maps.GeocoderStatus.OK) {
callBack = callBack + '&address=' + results[0].formatted_address;
callBack = callBack + '&coordinates=' + results[0].geometry.location;
}
callBack = callBack + '&status=' + status; Wicket.Ajax.ajax({
'u':callBack
});
});
}
} Wicket.maps = {} function WicketMap(id, failSilently) {
Wicket.maps[id] = this; if(failSilently) {
Wicket.maps['_failSilently'] = failSilently;
} this.options = {};
try {
this.map = new google.maps.Map(Wicket.$(id));
} catch (e) {
if(!failSilently) {
throw e;
}
}
this.overlays = {}; this.onEvent = function(callBack, params) {
params['center'] = this.map.getCenter();
params['bounds'] = this.map.getBounds();
params['zoom'] = this.map.getZoom();
params['currentMapType'] = this.getMapTypeString(this.map.getMapTypeId()); for ( var key in params) {
callBack = callBack + '&' + key + '=' + params[key];
} Wicket.Ajax.ajax({
'u':callBack
});
} this.addListener = function(event, callBack) {
var self = this; google.maps.event.addListener(this.map, event, function() {
var params = {};
for ( var p = 0; p < arguments.length; p++) { if (arguments[p] != null) {
if (arguments[p].latLng != null)
{
params['lat'] = arguments[0].latLng.lat();
params['lng'] = arguments[0].latLng.lng();
}
}
} self.onEvent(callBack, params);
});
} this.addOverlayListener = function(overlayID, event) {
var self = this;
var overlay = this.overlays[overlayID]; google.maps.event.addListener(overlay, event, function() {
var params = {};
for ( var p = 0; p < arguments.length; p++) {
if (arguments[p] != null) {
params['argument' + p] = arguments[p];
}
} if (overlay.getPosition) {
params['overlay.latLng'] = overlay.getPosition();
}
else if (overlay.getCenter) {
// Circle uses #getCenter() instead
params['overlay.latLng'] = overlay.getCenter();
} if (overlay.getRadius) {
// Circle
params['overlay.radius'] = overlay.getRadius();
} if (overlay.getBounds) {
params['overlay.bounds'] = overlay.getBounds();
} params['overlay.overlayId'] = overlay.overlayId;
params['overlay.event'] = event; self.onEvent(self.overlayListenerCallbackUrl, params);
});
} this.clearOverlayListeners = function(overlayID, event) {
var overlay = this.overlays[overlayID]; google.maps.event.clearListeners(overlay, event);
} this.setDraggingEnabled = function(enabled) {
this.options.draggable = enabled;
this.map.setOptions(this.options);
} this.setDoubleClickZoomEnabled = function(enabled) {
this.options.disableDoubleClickZoom = enabled;
this.map.setOptions(this.options);
} this.setScrollWheelZoomEnabled = function(enabled) {
this.options.scrollwheel = enabled;
this.map.setOptions(this.options);
} this.setScaleControlEnabled = function(enabled) {
this.options.scaleControl = enabled;
this.map.setOptions(this.options);
} this.setZoomControlEnabled = function(enabled) {
this.options.zoomControl = enabled;
this.map.setOptions(this.options);
} this.setMapTypeControlEnabled = function(enabled) {
this.options.mapTypeControl = enabled;
this.map.setOptions(this.options);
} this.setStreetViewControlEnabled = function(enabled) {
this.options.streetViewControl = enabled;
this.map.setOptions(this.options);
} this.setPanControlEnabled = function(enabled) {
this.options.panControl = enabled;
this.map.setOptions(this.options);
} this.fitBounds = function(bounds) {
this.options.bounds = bounds;
this.map.setOptions(this.options);
this.map.fitBounds(bounds);
} this.panToBounds = function(bounds) {
this.options.bounds = bounds;
this.map.setOptions(this.options);
this.map.panToBounds(bounds);
} this.setMinZoom = function(minZoom) {
this.options.minZoom = minZoom;
this.map.setOptions(this.options);
} this.setMaxZoom = function(maxZoom) {
this.options.maxZoom = maxZoom;
this.map.setOptions(this.options);
} this.getMapTypeString = function(mapType) {
switch (mapType) {
case google.maps.MapTypeId.ROADMAP:
return 'ROADMAP';
break;
case google.maps.MapTypeId.SATELLITE:
return 'SATELLITE';
break;
case google.maps.MapTypeId.HYBRID:
return 'HYBRID';
break;
case google.maps.MapTypeId.TERRAIN:
return 'TERRAIN';
break;
default:
return 'unknown';
break;
}
} this.setMapType = function(mapType) {
this.map.setMapTypeId(mapType);
} this.setZoom = function(level) {
this.map.setZoom(level);
} this.setCenter = function(center) {
    //设置地图中心
this.map.setCenter(center);
} this.setCenterFailSafe = function(lat, lng, unbounded) {
try {
this.map.setCenter( new google.maps.LatLng(lat, lng, unbounded) );
} catch (e) {
// do nothing
}
} this.panTo = function(center) {
this.map.panTo(center);
} this.panDirection = function(dx, dy) {
this.map.panBy(dx, dy);
} this.zoomOut = function() {
this.map.setZoom(this.map.getZoom()-1)
} this.zoomIn = function() {
this.map.setZoom(this.map.getZoom()+1)
} this.addOverlay = function(overlayId, overlay) {
this.overlays[overlayId] = overlay;
overlay.overlayId = overlayId;
overlay.setMap(this.map);
overlay.toString = function() {
return overlayId;
};
} this.removeOverlay = function(overlayId) {
if (this.overlays[overlayId] != null) {
this.overlays[overlayId].setMap(null);
this.overlays[overlayId] = null;
}
} this.clearOverlays = function() {
if (this.overlays) {
for (i in this.overlays) {
this.overlays[i].setMap(null);
}
}
this.overlays = {};
} this.triggerEvent = function(event) {
google.maps.event.trigger(this.map, event);
} this.triggerResize = function() {
this.triggerEvent('resize');
}
} Wicket.Event.add(window, "load", function(event){
if(typeof(Wicket.geocoder) === 'undefined') Wicket.geocoder = new WicketClientGeocoder();
});

 Java部分的实现,可以看出其属性与客户端的JS是一一对应的,这是Vicket的一种机制,将服务端的对象映射到客户端,这样在服务端设置属性就跟在客户端设置一样:

/*
*
* ==============================================================================
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.wicketstuff.gmap; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.wicket.Component;
import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.request.IRequestParameters;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.util.string.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wicketstuff.gmap.api.GEvent;
import org.wicketstuff.gmap.api.GLatLng;
import org.wicketstuff.gmap.api.GLatLngBounds;
import org.wicketstuff.gmap.api.GMapType;
import org.wicketstuff.gmap.api.GMarker;
import org.wicketstuff.gmap.api.GMarkerCluster;
import org.wicketstuff.gmap.api.GMarkerOptions;
import org.wicketstuff.gmap.api.GOverlay;
import org.wicketstuff.gmap.event.GEventListenerBehavior; /**
* Wicket component to embed <a href="http://maps.google.com">Google Maps</a> into your pages.
* <p>
*/
public class GMap extends Panel implements GOverlayContainer
{ /** log. */
private static final Logger log = LoggerFactory.getLogger(GMap.class);
private static final long serialVersionUID = 1L;
// Center is Palo Alto
private GLatLng center = new GLatLng(37.4419, -122.1419);
private boolean draggingEnabled = true;
private boolean doubleClickZoomEnabled = false;
private boolean scrollWheelZoomEnabled = false;
private boolean streetViewControlEnabled = false;
private boolean zoomControlEnabled = true;
private boolean mapTypeControlEnabled = true;
private boolean scaleControlEnabled = false;
private boolean panControlEnabled = true;
private GMapType mapType = GMapType.ROADMAP;
private int zoom = 13;
private int minZoom = 0;
private int maxZoom = 0;
private final Map<String, GOverlay> overlays = new HashMap<String, GOverlay>();
protected final WebMarkupContainer map;
private GLatLngBounds bounds;
private OverlayListener overlayListener = null;
private List<GLatLng> markersToShow = new ArrayList<GLatLng>(); /**
* If set to true map loading will not produce any JavaScript errors in case
* google maps API cannot be found (e.g. no Internet connection)
*/
private boolean failSilently = false;
private GMarkerCluster markerCluster; /**
* Constructor.
*
* Default the header contributor of the component will added and the gmap
* will be initiated directly on rendering of the map.
*
* @param id wicket id
* @param apiKey your Google API key
*/
public GMap(final String id, String apiKey)
{
this(id, new GMapHeaderContributor("http", apiKey));
} /**
* Constructor.
*
* Default the header contributor of the component will added and the gmap
* will be initiated directly on rendering of the map.
*
* @param id wicket id
* @param scheme the scheme ("http" or "https") which should be used
* @param apiKey your Google API key
*/
public GMap(final String id, String apiKey, String scheme)
{
this(id, new GMapHeaderContributor(scheme, apiKey));
} /**
* Construct.
*
* Default the header contributor of the component will added and the gmap
* will be initiated directly on rendering of the map.
*
* @param id wicket id
* @deprecated since 22th June 2016 Google Maps requires an API-key,
* therefore you should use
* {@link #GMap(java.lang.String, java.lang.String) } or {@link #GMap(java.lang.String, java.lang.String, java.lang.String)
* }
* instead of this constructor
* @see
* http://googlegeodevelopers.blogspot.de/2016/06/building-for-scale-updates-to-google.html
*/
public GMap(final String id)
{
this(id, new GMapHeaderContributor());
} /**
* @deprecated Since the sensor-parameter is no longer required from Google
* {@link #GMap(java.lang.String, java.lang.String) } or {@link #GMap(java.lang.String, java.lang.String, java.lang.String)
* }
* instead of this constructor
*/
public GMap(final String id, final boolean sensor)
{
this(id, new GMapHeaderContributor(sensor));
} /**
* Construct.
*
* @param id
* @param headerContrib
*/
public GMap(final String id, final GMapHeaderContributor headerContrib)
{
super(id); if (headerContrib != null)
{
add(headerContrib);
} map = new WebMarkupContainer("map");
map.setOutputMarkupId(true);
add(map); overlayListener = getOverlayListener();
add(overlayListener); } protected OverlayListener getOverlayListener()
{
return new OverlayListener();
} /**
* @return the markup-id of the container
*/
public String getMapId()
{
return map.getMarkupId();
} @Override
protected void onBeforeRender()
{
super.onBeforeRender(); if (getApplication().usesDevelopmentConfig()
&& !getApplication().getMarkupSettings().getStripWicketTags())
{
log.warn("Application is in DEVELOPMENT mode && Wicket tags are not stripped,"
+ "Some Chrome Versions will not render the GMap."
+ " Change to DEPLOYMENT mode || turn on Wicket tags stripping." + " See:"
+ " http://www.nabble.com/Gmap2-problem-with-Firefox-3.0-to18137475.html.");
}
} @Override
public void renderHead(IHeaderResponse response)
{
response.render(OnDomReadyHeaderItem.forScript(getJSinit()));
} /**
* Add an overlay.
*
* @see GOverlayContainer#addOverlay(GOverlay)
* @param overlay
* overlay to add
* @return This
*/
@Override
public GMap addOverlay(final GOverlay overlay)
{
overlays.put(overlay.getId(), overlay);
overlay.setParent(this); AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(overlay.getJS());
} return this;
} /**
* Remove an overlay.
*
* @see GOverlayContainer#removeOverlay(GOverlay)
* @param overlay
* overlay to remove
* @return This
*/
@Override
public GMap removeOverlay(final GOverlay overlay)
{
while (overlays.containsKey(overlay.getId()))
{
overlays.remove(overlay.getId());
} AjaxRequestTarget target = RequestCycle.get().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(overlay.getJSremove());
} overlay.setParent(null); return this;
} /**
* Clear all overlays.
*
* @see GOverlayContainer#removeAllOverlays()
* @return This
*/
@Override
public GMap removeAllOverlays()
{
for (final GOverlay overlay : overlays.values())
{
overlay.setParent(null);
}
overlays.clear();
AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSinvoke("clearOverlays()"));
}
return this;
} /**
* @see GOverlayContainer#getOverlays()
*/
@Override
public List<GOverlay> getOverlays()
{
return Collections.unmodifiableList(new ArrayList<GOverlay>(overlays.values()));
} public GLatLngBounds getBounds()
{
return bounds;
} public void setBounds(GLatLngBounds bounds)
{
this.bounds = bounds;
} /**
* Returns the script for triggering an event on map.
*
* @param event
* @return
*/
public CharSequence getTriggerEventScript(String event) {
return "Wicket.maps['"+getMapId()+ "'].triggerEvent('"+event+"')";
} /**
* @return returns the script to make map re-paint after resize.
*/
public CharSequence getTriggerResizeScript() {
return "Wicket.maps['"+getMapId()+ "'].triggerResize();";
} /**
* Sets if dragging should be allowed or not.
* @param enabled true if dragging should be allowed, false otherwise
*/
public void setDraggingEnabled(final boolean enabled)
{
if (this.draggingEnabled != enabled)
{
draggingEnabled = enabled; AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetDraggingEnabled(enabled));
}
}
} /**
* Is dragging allowed? Enabled by default.
*
* @return true if it's allowed, false if not
*/
public boolean isDraggingEnabled()
{
return draggingEnabled;
} /**
* Sets if zooming-by-doubleclicking should be allowed or not.
* @param enabled true if zooming-by-doubleclicking should be allowed, false otherwise
*/
public void setDoubleClickZoomEnabled(final boolean enabled)
{
if (this.doubleClickZoomEnabled != enabled)
{
doubleClickZoomEnabled = enabled; AjaxRequestTarget target = RequestCycle.get().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetDoubleClickZoomEnabled(enabled));
}
}
} /**
* Is the function zooming-by-doubleclick enabled?
* Disabled by default.
*
* @return true if enabled, false if disabled
*/
public boolean isDoubleClickZoomEnabled()
{
return doubleClickZoomEnabled;
} /**
* Sets if zooming-by-mousewheel should be allowed or not.
* @param enabled true if zooming-by-mousewheel should be allowed, false otherwise
*/
public void setScrollWheelZoomEnabled(final boolean enabled)
{
if (this.scrollWheelZoomEnabled != enabled)
{
scrollWheelZoomEnabled = enabled; AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetScrollWheelZoomEnabled(enabled));
}
}
} /**
* Is the function zooming-by-mousewheel enabled?
* Disabled by default.
*
* @return true if enabled, false if disabled
*/
public boolean isScrollWheelZoomEnabled()
{
return scrollWheelZoomEnabled;
} /**
* Is the StreetView control enabled?
* Disabled by default.
*
* @return true if enabled, false if disabled
*/
public boolean isStreetViewControlEnabled()
{
return streetViewControlEnabled;
} /**
* Sets if the StreeView control should be visible or not.
* @param enabled true if StreetView should be allowed, false otherwise
*/
public void setStreetViewControlEnabled(boolean enabled)
{
if (this.streetViewControlEnabled != enabled)
{
streetViewControlEnabled = enabled; AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetStreetViewControlEnabled(enabled));
}
}
} /**
* Is the zoom control enabled?
* Enabled by default.
*
* @return true if enabled, false if disabled
*/
public boolean isZoomControlEnabled()
{
return zoomControlEnabled;
} /**
* Sets if the zoom control should be visible or not.
* @param enabled true if the zoom-control should be enabled, false otherwise
*/
public void setZoomControlEnabled(boolean enabled)
{
if (this.zoomControlEnabled != enabled)
{
this.zoomControlEnabled = enabled; AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetZoomControlEnabled(enabled));
}
}
} /**
* Is the map type control enabled?
* Enabled by default.
*
* @return true if enabled, false if disabled
*/
public boolean isMapTypeControlEnabled()
{
return mapTypeControlEnabled;
} /**
* Sets if the map type control should be visible or not.
* @param enabled true if you want the user to have the possibility to
* change the map type, false otherwise
*/
public void setMapTypeControlEnabled(boolean enabled)
{ if (this.mapTypeControlEnabled != enabled)
{
this.mapTypeControlEnabled = enabled; AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetMapTypeControlEnabled(enabled));
}
}
} /**
* Is the scale control enabled?
* Disabled by default.
*
* @return true if enabled, false if disabled
*/
public boolean isScaleControlEnabled()
{
return scaleControlEnabled;
} /**
* Sets if the scale control should be visible or not.
* @param enabled true if the scale-control should be enabled, false otherwise
*/
public void setScaleControlEnabled(boolean enabled)
{
if (this.scaleControlEnabled != enabled)
{
this.scaleControlEnabled = enabled; AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetScaleControlEnabled(enabled));
}
}
} /**
* Is the pan control enabled?
* Enabled by default.
*
* @return true if enabled, false if disabled
*/
public boolean isPanControlEnabled()
{
return panControlEnabled;
} /**
* Sets if the pan control should be visible or not.
* @param enabled true if the pan-control should be enabled, false otherwise
*/
public void setPanControlEnabled(boolean enabled)
{
if (this.panControlEnabled != enabled)
{
this.panControlEnabled = enabled; AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetPanControlEnabled(enabled));
}
}
} /**
* @return the current map type.
* @see GMapType
*/
public GMapType getMapType()
{
return mapType;
} /**
* Sets the map type which should be used.
* @param mapType the map type
* @see GMapType
*/
public void setMapType(final GMapType mapType)
{
if (this.mapType != mapType)
{
this.mapType = mapType; AjaxRequestTarget target = RequestCycle.get().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(mapType.getJSsetMapType(GMap.this));
}
}
} /**
* @return the current zoom level
*/
public int getZoom()
{
return zoom;
} /**
* @return the minZoom level
*/
public int getMinZoom()
{
return minZoom;
} /**
* @return the maxZoom level
*/
public int getMaxZoom()
{
return maxZoom;
} /**
* Sets a new zoom level.
* @param level the new zoom level
*/
public void setZoom(final int level)
{
if (this.zoom != level)
{
this.zoom = level; AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetZoom(zoom));
}
}
} /**
* Sets a new minZoom limit.
* @param level the new minZoom level
*/
public void setMinZoom(final int level)
{
if (this.minZoom != level)
{
this.minZoom = level >= 0 ? level : 0; AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetMinZoom(minZoom));
}
}
} /**
* Sets a new maxZoom limit.
* @param level the new maxZoom level
*/
public void setMaxZoom(final int level)
{
if (this.maxZoom != level)
{
this.maxZoom = level >= 0 ? level : 0; AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetMaxZoom(maxZoom));
}
}
} /**
* @return the current center point
*/
public GLatLng getCenter()
{
return center;
} /**
* Set the center.
*
* @param center
* center to set
*/
public void setCenter(final GLatLng center)
{
if (!this.center.equals(center))
{
this.center = center; AjaxRequestTarget target = RequestCycle.get().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSsetCenter(center));
}
}
} /**
* Changes the center point of the map to the given point. If the point is already visible in the current map view,
* change the center in a smooth animation.
*
* @param center
* the new center of the map
*/
public void panTo(final GLatLng center)
{
if (!this.center.equals(center))
{
this.center = center; AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class);
if (target != null && findPage() != null)
{
target.appendJavaScript(getJSpanTo(center));
}
}
} public void setMarkerCluster(GMarkerCluster markerCluster)
{
if(markerCluster == null)
throw new IllegalArgumentException("GMarkerCluster argument should not be null.");
this.markerCluster = markerCluster;
if (getBehaviors(GMapMarkerClustererHeaderContributor.class).isEmpty())
{
add(new GMapMarkerClustererHeaderContributor());
}
} public boolean isMarkerClusterEnabled()
{
return markerCluster != null;
} /**
* Generates the JavaScript used to instantiate this GMap3 as an JavaScript class on the client side.
*
* @return The generated JavaScript
*/
public String getJSinit()
{
final StringBuilder js = new StringBuilder("new WicketMap('" + getMapId() + "', "+isFailSilently() +");\n"); js.append(getJSinvoke("clearOverlays()"));
js.append(overlayListener.getJSinit());
js.append(getJSsetCenter(getCenter()));
js.append(getJSsetZoom(getZoom()));
js.append(getJSsetMinZoom(getMinZoom()));
js.append(getJSsetMaxZoom(getMaxZoom()));
js.append(getJSfitBounds());
js.append(getJSsetDraggingEnabled(draggingEnabled));
js.append(getJSsetDoubleClickZoomEnabled(doubleClickZoomEnabled));
js.append(getJSsetScrollWheelZoomEnabled(scrollWheelZoomEnabled));
js.append(getJSsetStreetViewControlEnabled(streetViewControlEnabled));
js.append(getJSsetZoomControlEnabled(zoomControlEnabled));
js.append(getJSsetScaleControlEnabled(scaleControlEnabled));
js.append(getJSsetMapTypeControlEnabled(mapTypeControlEnabled));
js.append(getJSsetPanControlEnabled(panControlEnabled));
js.append(getJSFitMarkers());
js.append(mapType.getJSsetMapType(this)); // Add the overlays.
for (final GOverlay overlay : overlays.values())
{
js.append(overlay.getJS());
}
for (final Object behavior : getBehaviors(GEventListenerBehavior.class))
{
js.append(((GEventListenerBehavior) behavior).getJSaddListener());
} js.append(getJSMarkerCluster()); return js.toString();
} /**
* Convenience method for generating a JavaScript call on this GMap with the given invocation.
*
* @param invocation
* The JavaScript call to invoke on this GMap.
* @return The generated JavaScript.
*/
public String getJSinvoke(final String invocation)
{
return getJsReference() + "." + invocation + ";\n";
} /**
* Build a reference in JS-Scope.
*/
public String getJsReference()
{
return "Wicket.maps['" + getMapId() + "']";
} /**
* @see #fitMarkers(List, boolean, double)
*/
public void fitMarkers(final List<GLatLng> markersToShow)
{
fitMarkers(markersToShow, false, 0.0);
} /**
* @see #fitMarkers(List, boolean, double)
*/
public void fitMarkers(final List<GLatLng> markersToShow, final boolean showMarkersForPoints)
{
fitMarkers(markersToShow, showMarkersForPoints, 0.0);
} /**
* <p>
* Makes the map zoom out and centre around all the GLatLng points in markersToShow.
* <p>
* Big ups to Doug Leeper for the code.
*
* @see <a href= "http://www.nabble.com/Re%3A-initial-GMap2-bounds-question-p19886673.html" >Doug's Nabble post</a>
* @param markersToShow
* the points to centre around.
* @param showMarkersForPoints
* if true, will also add basic markers to the map for each point focused on. Just a simple convenience
* method - you will probably want to turn this off so that you can show more information with each
* marker when clicked etc.
*/
public void fitMarkers(final List<GLatLng> markersToShow, final boolean showMarkersForPoints,
final double zoomAdjustment)
{
this.markersToShow = markersToShow; // show the markers
if (showMarkersForPoints)
{
for (final GLatLng location : markersToShow)
{
this.addOverlay(new GMarker(new GMarkerOptions(this, location)));
}
}
} private String getJSFitMarkers() {
if (markersToShow.isEmpty())
{
return "";
} final StringBuilder buf = new StringBuilder();
buf.append("var bounds = new google.maps.LatLngBounds();\n");
// Ask google maps to keep extending the bounds to include each point
for (final GLatLng point : markersToShow)
{
buf.append("bounds.extend( ").append(point.getJSconstructor()).append(" );\n");
} buf.append(getJSinvoke("fitBounds(bounds)"));
buf.append(getJSinvoke("panToBounds(bounds)")); return buf.toString();
} private String getJSsetDraggingEnabled(final boolean enabled)
{
return getJSinvoke("setDraggingEnabled(" + enabled + ")");
} private String getJSsetDoubleClickZoomEnabled(final boolean enabled)
{
return getJSinvoke("setDoubleClickZoomEnabled(" + enabled + ")");
} private String getJSsetScrollWheelZoomEnabled(final boolean enabled)
{
return getJSinvoke("setScrollWheelZoomEnabled(" + enabled + ")");
} private String getJSsetStreetViewControlEnabled(final boolean enabled)
{
return getJSinvoke("setStreetViewControlEnabled(" + enabled + ")");
} private String getJSsetZoomControlEnabled(final boolean enabled)
{
return getJSinvoke("setZoomControlEnabled(" + enabled + ")");
} private String getJSsetScaleControlEnabled(final boolean enabled)
{
return getJSinvoke("setScaleControlEnabled(" + enabled + ")");
} private String getJSsetMapTypeControlEnabled(final boolean enabled)
{
return getJSinvoke("setMapTypeControlEnabled(" + enabled + ")");
} private String getJSsetPanControlEnabled(final boolean enabled)
{
return getJSinvoke("setPanControlEnabled(" + enabled + ")");
} private String getJSsetZoom(final int zoom)
{
return getJSinvoke("setZoom(" + zoom + ")");
} private String getJSsetMinZoom(final int minZoom)
{
return getJSinvoke("setMinZoom(" + minZoom + ")");
} private String getJSsetMaxZoom(final int maxZoom)
{
return getJSinvoke("setMaxZoom(" + maxZoom + ")");
} /**
* Build the JavaScript for fitBounds() with the bounds property
*
* @return JavaScript for the fitBounds-Function
*/
private String getJSfitBounds() {
if (null == bounds || Strings.isEmpty(bounds.getJSconstructor())) {
return "";
} // else
return getJSinvoke("fitBounds(" + bounds.getJSconstructor() + ")");
} private String getJSsetCenter(final GLatLng center)
{
if (center != null)
{
if( !failSilently )
{
return getJSinvoke("setCenter(" + center.getJSconstructor() + ")");
} else {
return getJSinvoke("setCenterFailSafe(" + center.getArguments() + ")");
}
}
return "";
} private String getJSpanDirection(final int dx, final int dy)
{
return getJSinvoke("panDirection(" + dx + "," + dy + ")");
} private String getJSpanTo(final GLatLng center)
{
return getJSinvoke("panTo(" + center.getJSconstructor() + ")");
} private String getJSzoomOut()
{
return getJSinvoke("zoomOut()");
} private String getJSzoomIn()
{
return getJSinvoke("zoomIn()");
} private String getJSMarkerCluster()
{
if(markerCluster != null)
{ return markerCluster.getJSconstructor();
}
return "";
} /**
* Update state from a request to an AJAX target.
* You need to call this method explictly if you want to have up-to-date values.
*/
public void update()
{
// Attention: don't use setters as this will result in an endless
// AJAX request loop
IRequestParameters requestParameters = getRequest().getRequestParameters();
bounds = GLatLngBounds.parse(requestParameters.getParameterValue("bounds").toString());
center = GLatLng.parse(requestParameters.getParameterValue("center").toString());
zoom = requestParameters.getParameterValue("zoom").toInt(zoom);
String requestMapType = requestParameters.getParameterValue("currentMapType").toString();
mapType = requestMapType != null ? GMapType.valueOf(requestParameters.getParameterValue("currentMapType").toString()) : mapType;
} public void setOverlays(final List<GOverlay> overlays)
{
removeAllOverlays();
for (final GOverlay overlay : overlays)
{
addOverlay(overlay);
}
} private static abstract class JSMethodBehavior extends Behavior
{
private static final long serialVersionUID = 1L;
private final String attribute; public JSMethodBehavior(final String attribute)
{
this.attribute = attribute;
} @Override
public void onComponentTag(final Component component, final ComponentTag tag)
{
String invoke = getJSinvoke(); if (attribute.equalsIgnoreCase("href"))
{
invoke = "javascript:" + invoke;
} tag.put(attribute, invoke);
} protected abstract String getJSinvoke();
} public class ZoomOutBehavior extends JSMethodBehavior
{
private static final long serialVersionUID = 1L; public ZoomOutBehavior(final String event)
{
super(event);
} @Override
protected String getJSinvoke()
{
return getJSzoomOut();
}
} public class ZoomInBehavior extends JSMethodBehavior
{
private static final long serialVersionUID = 1L; public ZoomInBehavior(final String event)
{
super(event);
} @Override
protected String getJSinvoke()
{
return getJSzoomIn();
}
} public class PanDirectionBehavior extends JSMethodBehavior
{
private static final long serialVersionUID = 1L;
private final int dx;
private final int dy; public PanDirectionBehavior(final String event, final int dx, final int dy)
{
super(event);
this.dx = dx;
this.dy = dy;
} @Override
protected String getJSinvoke()
{
return getJSpanDirection(dx, dy);
}
} public class SetZoomBehavior extends JSMethodBehavior
{
private static final long serialVersionUID = 1L;
private final int zoomBehavior; public SetZoomBehavior(final String event, final int zoom)
{
super(event);
zoomBehavior = zoom;
} @Override
protected String getJSinvoke()
{
return getJSsetZoom(zoomBehavior);
}
} public class SetCenterBehavior extends JSMethodBehavior
{
private static final long serialVersionUID = 1L;
private final GLatLng gLatLng; public SetCenterBehavior(final String event, final GLatLng gLatLng)
{
super(event);
this.gLatLng = gLatLng;
} @Override
protected String getJSinvoke()
{
return getJSsetCenter(gLatLng);
}
} public class SetMapTypeBehavior extends JSMethodBehavior
{
private static final long serialVersionUID = 1L;
private final GMapType mapTypeBehavior; public SetMapTypeBehavior(final String event, final GMapType mapType)
{
super(event);
mapTypeBehavior = mapType;
} @Override
protected String getJSinvoke()
{
return mapTypeBehavior.getJSsetMapType(GMap.this);
}
} public class OverlayListener extends AbstractDefaultAjaxBehavior
{
private static final long serialVersionUID = 1L; @Override
protected void respond(final AjaxRequestTarget target)
{
final Request request = RequestCycle.get().getRequest(); final String overlayId = request.getRequestParameters().getParameterValue("overlay.overlayId").toString().replace("overlay", "");
final String event = request.getRequestParameters().getParameterValue("overlay.event").toString();
final GOverlay overlay = overlays.get(overlayId);
if (overlay != null)
{
overlay.onEvent(target, GEvent.valueOf(event));
}
} public Object getJSinit()
{
return GMap.this.getJSinvoke("overlayListenerCallbackUrl = '" + this.getCallbackUrl() + "'"); }
} public boolean isFailSilently() {
return failSilently;
} public void setFailSilently(boolean failSilently) {
this.failSilently = failSilently;
}
}

 看下怎么往地图上添加标记,可以看到我们不用直接在客户端写JS,服务端操作即可:

	private GMap buildGui() {

		final EntityModel model = getModel();
final ObjectAdapter adapter = model.getObject();
Location l = (Location) adapter.getObject();
GLatLng latLng = new GLatLng(l.getLatitude(), l.getLongitude()); final boolean visible = latLng != null; final GMap map = new GMap(ID_MAP, apiKey);
// map.setStreetViewControlEnabled(true);
map.setScaleControlEnabled(false);
map.setPanControlEnabled(false);
map.setDoubleClickZoomEnabled(false);
map.setZoom(17); if (visible) { // centre the map on the first object that has a location.
map.setCenter(latLng);
} addOrReplace(map); addMarker(map, adapter); return map;
} private void addMarker(final GMap map, ObjectAdapter adapter) { ObjectAdapter dereferencedAdapter = dereference(adapter); final GMarker gMarker = createGMarker(map, adapter, dereferencedAdapter);
if (gMarker != null) {
map.addOverlay(gMarker);
// addClickListener(gMarker, dereferencedAdapter);
}
List<GLatLng> glatLngsToShow = Lists.newArrayList();
map.fitMarkers(glatLngsToShow);
}

下边开始尝试替换相应的内容:

GMapHeaderContributor类,改成高德的接口

public class GMapHeaderContributor extends Behavior {

	private static final long serialVersionUID = 1L;
// URL for Google Maps' API endpoint.
private static final String GMAP_API_URL = "%s://webapi.amap.com/maps?v=1.3&key=%s";
private static final String HTTP = "http";
// We have some custom Javascript.
private static final ResourceReference WICKET_GMAP_JS = new JavaScriptResourceReference(GMap.class,
"wicket-gmap.js"); //...

wicket-gmap.js

//...
//地图对象的实例化
function WicketClientGeocoder() { this.coder = new AMap.Geocoder(); this.getLatLng = function(callBack, addressId){ var address = Wicket.$(addressId).value; this.coder.geocode({
'address': address
}, function(results, status){ var params = {};
if (status == AMap.GeocoderStatus.OK) {
params['address'] = results[0].formatted_address;
params['coordinates'] = results[0].geometry.location;
params['status'] = status;
} for ( var key in params) {
callBack = callBack + '&' + key + '=' + params[key];
} Wicket.Ajax.ajax({
'u':callBack,
'ep': params
});
});
}
} //其它API有差异的地方也相应的改一下,此处略
//...

实现集合页UI适配工厂:

/*
* Copyright 2013~2014 Dan Haywood
*
* Licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.itisys.map.ui; import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.UnknownHostException; import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.viewer.wicket.model.models.EntityCollectionModel;
import org.apache.isis.viewer.wicket.ui.CollectionContentsAsFactory;
import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
import org.apache.isis.viewer.wicket.ui.ComponentType;
import org.apache.wicket.Component;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model; import com.itisys.map.applib.AmapApplibConstants;
import com.itisys.map.applib.Locatable; public class CollectionOfEntitiesAsLocatablesFactory extends ComponentFactoryAbstract implements CollectionContentsAsFactory { private static final long serialVersionUID = 1L; private static final String ID_MAP = "map"; private boolean determinedWhetherInternetReachable;
private boolean internetReachable; public CollectionOfEntitiesAsLocatablesFactory() {
super(ComponentType.COLLECTION_CONTENTS, ID_MAP);
} @Override
public ApplicationAdvice appliesTo(IModel<?> model) { final String apiKey = getConfiguration().getString(AmapApplibConstants.API_KEY);
if(apiKey == null) {
return ApplicationAdvice.DOES_NOT_APPLY;
} if(!internetReachable()) {
return ApplicationAdvice.DOES_NOT_APPLY;
} if (!(model instanceof EntityCollectionModel)) {
return ApplicationAdvice.DOES_NOT_APPLY;
} EntityCollectionModel entityCollectionModel = (EntityCollectionModel) model; ObjectSpecification typeOfSpec = entityCollectionModel.getTypeOfSpecification();
ObjectSpecification locatableSpec = getSpecificationLoader().loadSpecification(Locatable.class);
return appliesIf(typeOfSpec.isOfType(locatableSpec));
} private boolean internetReachable() {
if(!determinedWhetherInternetReachable) {
internetReachable = isInternetReachable();
determinedWhetherInternetReachable = true;
}
return internetReachable;
} /**
* Tries to retrieve some content, 1 second timeout.
*/
private static boolean isInternetReachable()
{
try {
final URL url = new URL("http://www.amap.com");
final HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();
urlConnect.setConnectTimeout(1000);
urlConnect.getContent();
urlConnect.disconnect();
} catch (UnknownHostException e) {
return false;
} catch (IOException e) {
return false;
}
return true;
} public Component createComponent(String id, IModel<?> model) { final String apiKey = getConfiguration().getString(AmapApplibConstants.API_KEY); EntityCollectionModel collectionModel = (EntityCollectionModel) model;
return new CollectionOfEntitiesAsLocatables(id, apiKey, collectionModel);
} protected SpecificationLoader getSpecificationLoader() {
return IsisContext.getSessionFactory().getSpecificationLoader();
} protected IsisConfiguration getConfiguration() {
return IsisContext.getSessionFactory().getConfiguration();
} @Override
public IModel<String> getTitleLabel() {
return Model.of("Map");
} @Override
public IModel<String> getCssClass() {
return Model.of("fa fa-map-marker");
} }

实现实体属性UI适配:

/*
* Copyright 2013~2014 Dan Haywood
*
* Licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.itisys.map.ui; import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.viewer.wicket.model.models.ScalarModel;
import org.apache.isis.viewer.wicket.ui.components.scalars.ComponentFactoryScalarAbstract;
import org.apache.wicket.Component; import com.itisys.map.applib.AmapApplibConstants;
import com.itisys.map.applib.Location; public class EntityAsLocatablesFactory extends ComponentFactoryScalarAbstract { private static final long serialVersionUID = 1L; private static final String ID_MAP = "map"; public EntityAsLocatablesFactory() {
super(EntityAsLocatables.class, Location.class);
} protected SpecificationLoader getSpecificationLoader() {
return IsisContext.getSessionFactory().getSpecificationLoader();
} protected IsisConfiguration getConfiguration() {
return IsisContext.getSessionFactory().getConfiguration();
} @Override
protected Component createComponent(String id, ScalarModel scalarModel) {
final String apiKey = getConfiguration().getString(AmapApplibConstants.API_KEY);
return new EntityAsLocatables(id,apiKey, scalarModel);
} }

让isis支持高德地图的更多相关文章

  1. IOS原生地图与高德地图

    原生地图 1.什么是LBS LBS: 基于位置的服务   Location Based Service 实际应用:大众点评,陌陌,微信,美团等需要用到地图或定位的App 2.定位方式 1.GPS定位  ...

  2. 高德地图-搜索服务-POI搜索

    高德地图-搜索服务-POI搜索 之前公司项目收货地址仿饿了么的收货地址,结果发现自己实现的关键字搜索和周边搜索,搜索到的poi列表跟饿了么的并不完全一样,后来考虑了下,应该是搜索的范围.类型之类的设置 ...

  3. objective-c高德地图时时定位

    这篇随笔是对上一遍servlet接口的实现. 一.项目集成高德地图 应为我这个项目使用了cocopods这个第三方库管理工具,所以只需要很简单的步骤,就能将高德地图集成到项目中,如果你没使用过这工具, ...

  4. java servlet手机app访问接口(三)高德地图云存储及检索

    这篇关于高德地图的随笔内容会多一点, 一.业务说明     对应APP业务中的成员有两类,一是服务人员,二是被服务人员,  主要实现功能, 对APP中的服务人员位置进行时时定位, 然后通过被服务人员登 ...

  5. IOS高德地图逆地理编码定位+网络判断

    先说下这功能的流程,  流程:判断用户是否联网--->获取用户地理位置经纬度--->通过经纬度去查询地理位置名称 //高德地图 @property (nonatomic, strong) ...

  6. 高德地图API应用

    高德地图官网:http://api.amap.com/javascript/ 输入关键字,搜索地址功能的网页: 1.引用远程Map Api(js)网址形式(注册后获取) 2.定义个<div> ...

  7. Android笔记:百度地图与高德地图坐标转换问题

    安卓项目使用了百度地图的定位SDK,web端使用的也是百度地图, 后来发现界面显示百度地图不如高德效果好,web改用高德地图,原本的百度地图坐标是可以直接使用的,由于高德和百度地图的坐标系不一致 要如 ...

  8. 使用高德地图SDK获取定位信息

    使用高德地图SDK获取定位信息 第一步: 在高德官网下载SDK,如我这里需要获取定位信息,故仅下载"定位功能" 第二步: 注册成为开发者,并创建应用获取相应的key.其中,在使用A ...

  9. iOS之原生地图与高德地图

    原生地图 1.什么是LBS LBS: 基于位置的服务 Location Based Service 实际应用:大众点评,陌陌,微信,美团等需要用到地图或定位的App 2.定位方式 1.GPS定位 2. ...

随机推荐

  1. 01 使用Git基本方法

    什么是Git? Git是目前世界上最先进的分布式版本控制系统(没有之一). 你得先有一个Git仓库,才能进行操作.创库就是Git存放你要保存的快照的数据的地方. 拥有一个Git仓库,有两种方法. 创建 ...

  2. MapReduce详解和WordCount模拟

    最早接触大数据,常萦绕耳边的一个词「MapReduce」.它到底是什么,能做什么,原理又是什么?且听下文讲解. 是什么 MapReduce 即是一个编程模型,又是一个计算框架,它充分采用了分治的思想, ...

  3. 如何使用canvas进行2d绘图

    canvas 的 2D context 可以绘制简单的 2D 图形.它的 2D context 坐标开始于 <canvas> 元素的左上角,原点坐标是(0,0).所有的坐标值都基于这个原点 ...

  4. Linux 中常用命令

    命令基本格式: 命令提示符:[root@localhost ~]#      root 代表当前的登录用户(linux当中管理员账号是root)      @ 无实际意义      localhost ...

  5. #include <unistd.h> 的作用

    原文:http://blog.csdn.net/ybsun2010/article/details/24832113 由字面意思,unistd.h是unix std的意思,是POSIX标准定义的uni ...

  6. jquery 仿windows10菜单效果下载

    http://www.kuitao8.com/20150923/4079.shtml jquery 仿windows10菜单效果下载

  7. Mac安装Dart的SDK

    最近了解到谷歌推迟Flutter兼容开发iOS.Android移动应用的框架,该框架使用的语音是Dart.作为一个iOS开发者来说,不感兴趣就不正常了,于是开始从学习Dart开始,所有的开发语音其实都 ...

  8. 弧形菜单2(动画渐入)Kotlin开发(附带java源码)

    弧形菜单2(动画渐入+Kotlin开发) 前言:基于AndroidStudio的采用Kotlin语言开发的动画渐入的弧形菜单...... 效果: 开发环境:AndroidStudio2.2.1+gra ...

  9. 服务器端的tomcat,servlet框架

    tomcat是一个服务器程序 可以对webapp目录下的Servlet代码进行执行和操作 编写的Servlet代码的步骤一般是在本地的ide中编写和测试,然后打包工程为war格式的文件,部署在服务器t ...

  10. Java基础之基本数据类型的包装类型

    Java的基本数据类型的包装数据类型有多种: int Integer,short Short,boolean Boolean,float Float,double Double等等. Java包装类数 ...