2012-07-24 262 views

回答

2

我做了類似的事情,但區域在我的情況下重疊,所以我需要:

canvas.clipPath(path, Op.DIFFERENCE); 

如果你想XML或KML輸入,只是解析/負載然而你想要把它轉換成GeoPoints,就像我用Loc對象做的那樣。

import java.util.*; 

import android.graphics.*; 
import android.graphics.Paint.Style; 
import android.graphics.Region.Op; 
import android.os.Bundle; 

import com.google.android.maps.*; 

public class ShapeOverlayTest extends MapActivity { 
    private MapView m_map; 

    @Override 
    public void onCreate(final Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     m_map = (MapView) findViewById(R.id.mapview); 
     m_map.displayZoomControls(true); 
     m_map.setBuiltInZoomControls(true); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 

     Loc[][] areas = { 
      { 
      new Loc(51.51695436113811, -0.28686325139653757), 
      new Loc(51.5268179962453, -0.28118722558738923), 
      new Loc(51.526498459594215, -0.27779666308279755), 
      new Loc(51.52521530775356, -0.26943974607777654), 
      new Loc(51.52292555645698, -0.25813738590178786), 
      new Loc(51.52054465991048, -0.2498381618983569), 
      new Loc(51.51012230470141, -0.24509233633017083), 
      new Loc(51.50884762913046, -0.24465130560570497), 
      new Loc(51.50732063336974, -0.2441767643132881), 
      new Loc(51.50431624597833, -0.24473900326760137), 
      new Loc(51.49756328092904, -0.2714528238165076), 
      new Loc(51.50092541797557, -0.28360267232347336), 
      new Loc(51.50205958485736, -0.28490018935582045), 
      new Loc(51.50488447379555, -0.28681164237730944) 
      }, 
      { 
      new Loc(51.50368617913765, -0.25313579464343156), 
      new Loc(51.51978611305675, -0.24842567405905958), 
      new Loc(51.51039382684418, -0.24460628015366626), 
      new Loc(51.508792552597576, -0.24397604687682156), 
      new Loc(51.50713008309719, -0.24346350415674722), 
      new Loc(51.502411013302684, -0.2508501075008919), 
      new Loc(51.502377240039664, -0.25160073203846817), 
      new Loc(51.50274364303565, -0.25204783703705536) 
      }, 
      { 
      new Loc(51.49924084955314, -0.2858705706471945), 
      new Loc(51.50212820259818, -0.2791479893522646), 
      new Loc(51.49724510427319, -0.27427453152961206), 
      new Loc(51.49429724502515, -0.2799184038304611), 
      new Loc(51.494270969987404, -0.28180678948730314) 
      } 
     }; 
     String[] areaNames = { "W3 Ealing", "W3 Hammersmith & Fulham", "W3 Hounslow" }; 

     // for (Map.Entry<String, List<Loc>> area : m_areas.entrySet()) { 
     // // to have much less points and make sure they are in order 
     // // the demo data already has these properties 
     // // http://en.wikipedia.org/wiki/Gift_wrapping_algorithm#Pseudocode 
     // area.setValue(Algo.convexHull(area.getValue())); 
     // } 

     Map<String, List<GeoPoint>> areaMap = new HashMap<String, List<GeoPoint>>(); 
     for (int i = 0; i < areaNames.length; i++) { 
      List<GeoPoint> points = new ArrayList<GeoPoint>(); 
      for (int j = 0; j < areas[i].length; j++) { 
       points.add(areas[i][j].toGeoPoint()); 
      } 
      areaMap.put(areaNames[i], points); 
     } 
     m_map.getOverlays().add(new AreasOverlay(areaMap)); 

     // TODO determine location better, e.g. averaging area points 
     GeoPoint center = new GeoPoint(51509704, -270710); 
     m_map.getController().setCenter(center); 
     m_map.getController().setZoom(15); 
    } 

    @Override 
    protected boolean isRouteDisplayed() { 
     return false; 
    } 

    static class Loc { 
     private double m_lat; 
     private double m_lon; 

     public Loc(final double lat, final double lon) { 
      m_lat = lat; 
      m_lon = lon; 
     } 

     public GeoPoint toGeoPoint() { 
      return new GeoPoint((int) (m_lat * 1e6), (int) (m_lon * 1e6)); 
     } 
    }; 

    static class AreasOverlay extends Overlay { 
     private final Map<String, List<GeoPoint>> m_areas; 
     private final Paint m_paintFill; 
     private final Paint m_paintStroke; 
     private static final int ALPHA = 0x30ffffff; // 48 out of 255 transparent 
     private static final int[] COLORS = 
     { Color.YELLOW, Color.MAGENTA, Color.CYAN, Color.RED, Color.GREEN, Color.BLUE }; 
     static { 
      for (int i = 0; i < AreasOverlay.COLORS.length; i++) { 
       AreasOverlay.COLORS[i] &= AreasOverlay.ALPHA; 
      } 
     } 

     public AreasOverlay(final Map<String, List<GeoPoint>> areaMap) { 
      m_areas = areaMap; 

      // prepare paints 
      m_paintFill = new Paint(); 
      m_paintFill.setStyle(Paint.Style.FILL); 
      m_paintStroke = new Paint(Paint.ANTI_ALIAS_FLAG); 
      m_paintStroke.setStyle(Style.STROKE); 
      m_paintStroke.setAntiAlias(true); 
      m_paintStroke.setStrokeWidth(3); 
     } 

     @Override 
     public void draw(final Canvas canvas, final MapView mapView, final boolean shadow) { 
      super.draw(canvas, mapView, shadow); 
      if (shadow) { 
       return; 
      } 
      Projection projection = mapView.getProjection(); 

      List<Path> areaPaths = getPaths(projection, m_areas); 
      drawPaths(canvas, areaPaths); 
     } 

     private List<Path> getPaths(final Projection projection, final Map<String, List<GeoPoint>> areas) { 
      List<Path> areaPaths = new ArrayList<Path>(areas.size()); 
      for (Map.Entry<String, List<GeoPoint>> entry : areas.entrySet()) { 
       List<GeoPoint> sourceList = entry.getValue(); 
       Path path = new Path(); 
       path.setFillType(Path.FillType.EVEN_ODD); 
       Iterator<GeoPoint> it = sourceList.iterator(); 
       Point point = nextDrawPoint(projection, it); 
       path.moveTo(point.x, point.y); 
       while (it.hasNext()) { 
        point = nextDrawPoint(projection, it); 
        path.lineTo(point.x, point.y); 
       } 
       path.close(); 
       areaPaths.add(path); 
      } 
      return areaPaths; 
     } 

     /** 
     * <ul> 
     * <li>Draw with different colors. 
     * <li>Draw strokes first for them to be always visible. 
     * <li>Draw fills next with each removing from the drawable area. 
     * </ul> 
     */ 
     private void drawPaths(final Canvas canvas, final List<Path> areaPaths) { 
      int currentColorIndex; 

      currentColorIndex = 0; 
      for (Path path : areaPaths) { 
       int currentColor = AreasOverlay.COLORS[currentColorIndex++]; 
       currentColorIndex %= AreasOverlay.COLORS.length; 
       m_paintStroke.setColor(currentColor & 0xff7f7f7f); // make it darker by clearing the high bit 
       canvas.drawPath(path, m_paintStroke); 
      } 
      currentColorIndex = 0; 
      for (Path path : areaPaths) { 
       int currentColor = AreasOverlay.COLORS[currentColorIndex++]; 
       currentColorIndex %= AreasOverlay.COLORS.length; 
       m_paintFill.setColor(currentColor); 
       canvas.drawPath(path, m_paintFill); 
       canvas.clipPath(path, Op.DIFFERENCE); // don't allow to draw over each other 
      } 
     } 

     private Point nextDrawPoint(final Projection projection, final Iterator<GeoPoint> it) { 
      GeoPoint geo = it.next(); 
      Point p = new Point(); 
      projection.toPixels(geo, p); 
      return p; 
     } 
    } 
} 
+0

嘿thx夥計。我做了類似於你的事情。然而,你知道任何方式,我可以正確使用創建的overflay形狀ontap函數?如果你在stackoverflow上閱讀我的另一個問題,我只會遇到ontap被調用的最後一個函數的問題 – ericlee 2012-07-26 07:43:07