2012-10-24 3 views
0

Je rencontre des problèmes avec les superpositions. J'ai dessiné une superposition de polygones sur la carte, cependant, lorsque j'effectue un zoom avant ou arrière, les bords ne s'alignent plus avec l'endroit où je le veux. Comment puis-je réparer cela?Comportement de superposition lors du zoom

Voici à quoi il ressemble quand je commence l'application (il couvre tout le terrain de stationnement parfaitement): Correct

Voici à quoi il ressemble quand je effectuer un zoom arrière (bords ne sont plus en ligne avec beaucoup de stationnement Le recouvrement semble un peu plus grand que le stationnement): Zoomed out

De plus, il ne s'aligne pas bien lorsque je zoome. Dans ce cas, la superposition est un peu plus petite que le stationnement. (Désolé, stackoverflow ne me laissera pas poster plus que 2 liens)

Des suggestions sur la façon de résoudre ce problème?

Voici le code:

private Projection projection; 
private List<Overlay> mapOverlays; 

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

    MapView mapView = (MapView) findViewById(R.id.mapView); 
    mapView.setBuiltInZoomControls(true); 

    MapController mc = mapView.getController(); 
    mc.setZoom(17); 
    mc.animateTo(new GeoPoint((int)(32.734248*1E6), (int)(-97.113448*1E6))); 

    mapOverlays = mapView.getOverlays();   
    projection = mapView.getProjection(); 
    mapOverlays.add(new MyOverlay());   

    mapView.postInvalidate(); 
} 

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

class MyOverlay extends Overlay{ 

    public MyOverlay(){ 

    } 

    public void draw(Canvas canvas, MapView mapv, boolean shadow){ 
     super.draw(canvas, mapv, shadow); 

     Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     mPaint.setColor(Color.RED); 
     mPaint.setStyle(Paint.Style.FILL); 
     mPaint.setAlpha(100); 

     GeoPoint gP1 = new GeoPoint(32733839,-97112976); 
     GeoPoint gP2 = new GeoPoint(32733875, -97113448); 
     GeoPoint gP3 = new GeoPoint(32734961,-97113455); 
     GeoPoint gP4 = new GeoPoint(32734953, -97112962); 

     Point p1 = new Point(); 
     Point p2 = new Point(); 
     Point p3 = new Point(); 
     Point p4 = new Point(); 
     Path path = new Path(); 

     projection.toPixels(gP1, p1); 
     projection.toPixels(gP2, p2); 
     projection.toPixels(gP3, p3); 
     projection.toPixels(gP4, p4); 

     path.moveTo(p1.x, p1.y); 
     path.lineTo(p2.x,p2.y); 
     path.lineTo(p3.x,p3.y); 
     path.lineTo(p4.x,p4.y); 

     canvas.drawPath(path, mPaint); 
    } 
} 

}

+0

Vous devriez publier du code car vous pourriez avoir des problèmes de précision. – bgs

+0

J'ai ajouté le code ci-dessus. – Kvothe

+0

Etes-vous sûr de avoir converti vos points [correctement] (http://stackoverflow.com/questions/2227816/how-to-give-double-value-to-geopoint-in-googlemap-overlays)? – bgs

Répondre

0

Chaque fois que le change de zoom, Projection change aussi. Même lorsque vous faites un grand mouvement sur la carte sans changer de zoom, la projection peut changer.

Pour corriger votre code, vous devez ajouter la ligne comme ci-dessous:

public void draw(Canvas canvas, MapView mapv, boolean shadow){ 
    super.draw(canvas, mapv, shadow); 

    Projection projection = mapv.getProjection(); //Add this line 

    Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mPaint.setColor(Color.RED); 
    mPaint.setStyle(Paint.Style.FILL); 
    mPaint.setAlpha(100); 

    GeoPoint gP1 = new GeoPoint(32733839,-97112976); 
    GeoPoint gP2 = new GeoPoint(32733875, -97113448); 
    GeoPoint gP3 = new GeoPoint(32734961,-97113455); 
    GeoPoint gP4 = new GeoPoint(32734953, -97112962); 

    Point p1 = new Point(); 
    Point p2 = new Point(); 
    Point p3 = new Point(); 
    Point p4 = new Point(); 
    Path path = new Path(); 

    projection.toPixels(gP1, p1); 
    projection.toPixels(gP2, p2); 
    projection.toPixels(gP3, p3); 
    projection.toPixels(gP4, p4); 

    path.moveTo(p1.x, p1.y); 
    path.lineTo(p2.x,p2.y); 
    path.lineTo(p3.x,p3.y); 
    path.lineTo(p4.x,p4.y); 

    canvas.drawPath(path, mPaint); 
} 

Et vous pouvez supprimer la projection créée en onCreate().

--EDITED--

Améliorations - rapide gagne

onDraw() est appelé deux fois, vous eveytime déplacez la carte ou de modifier le niveau de zoom, il est donc important de le rendre possible. Bellow vous pouvez trouver quelques suggestions:

private List<Overlay> mapOverlays; 

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

    MapView mapView = (MapView) findViewById(R.id.mapView); 
    mapView.setBuiltInZoomControls(true); 

    MapController mc = mapView.getController(); 
    mc.setZoom(17); 
    mc.animateTo(new GeoPoint((int)(32.734248*1E6), (int)(-97.113448*1E6))); 

    mapOverlays = mapView.getOverlays();   
    mapOverlays.add(new MyOverlay());   

    mapView.postInvalidate(); 
} 

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

class MyOverlay extends Overlay{ 

    //Moved objects that need only one instance to the initialization, to avoid creating a new copy of each every time draw() runs 
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 

    private GeoPoint gP1 = new GeoPoint(32733839,-97112976); 
    private GeoPoint gP2 = new GeoPoint(32733875, -97113448); 
    private GeoPoint gP3 = new GeoPoint(32734961,-97113455); 
    private GeoPoint gP4 = new GeoPoint(32734953, -97112962); 

    private Point p1 = new Point(); 
    private Point p2 = new Point(); 
    private Point p3 = new Point(); 
    private Point p4 = new Point(); 
    private Path path = new Path(); 

    public MyOverlay(){ 
     //mPaint settings done on class creation, to avoid repeating them on draw() call 
     mPaint.setColor(Color.RED); 
     mPaint.setStyle(Paint.Style.FILL); 
     mPaint.setAlpha(100); 
    }  

    public void draw(Canvas canvas, MapView mapv, boolean shadow){ 
     super.draw(canvas, mapv, shadow); 

     //draw is always called twice, one with shadow equal to true and one to false. 
     //This can be used to draw the same image with shadow 
     //But you are not using shadows, so you can immediately return half of the calls, and reduce the draw() effort by half 
     if(shadow) return; 

     Projection projection = mapv.getProjection(); 

     projection.toPixels(gP1, p1); 
     projection.toPixels(gP2, p2); 
     projection.toPixels(gP3, p3); 
     projection.toPixels(gP4, p4); 

     path.rewind(); 
     path.moveTo(p1.x,p1.y); 
     path.lineTo(p2.x,p2.y); 
     path.lineTo(p3.x,p3.y); 
     path.lineTo(p4.x,p4.y); 

     canvas.drawPath(path, mPaint); 
    } 
} 

Améliorations - un plus complexe un

L'amélioration que je décris ci-dessous est un surpuissant pour vous overlay en cours. Cela n'a de sens que lorsque vous avez vraiment de grands chemins à dessiner. Lorsque vous déplacez la carte, sans le zapper, le code au-dessus du chemin sera recréé et redessiné à un endroit différent pour être aligné avec la carte. Mais le chemin que vous créez est de la même taille, de la même forme que le précédent, juste dans une position différente.

Vous pouvez achive le même résultat en utilisant:

path.offset(dx, dy); 

dx, dy est le nombre de pixels dont vous avez besoin pour déplacer le chemin pour le maintenir aligné sur la carte. Bien sûr, vous devez garder la trace de la carte la dernière fois que vous avez décalé le chemin, de sorte que vous puissiez décaler le chemin vers la nouvelle position de la carte.

Si vous disposez d'un chemin avec plusieurs milliers de points, la compensation du chemin sera environ 100 fois plus rapide que la redessinaison.

Vous devez également suivre le niveau de zoom, car vous devez toujours recréer le chemin lorsque le zoom change. Vous ne pouvez pas utiliser getCurrentZoomLevel() pour le faire, car il n'est pas synchronisé avec l'animation de zoom. Vous devez tester les changements de valeur longitudeSpan() pour pouvoir créer une trajectoire synchronisée avec une animation de changement de zoom.

J'espère que cela aidera.

Cordialement.

+0

J'ai donc ajouté Projection projection = mapv.getProjection() ;. mapView est pour mapView dans onCreate(). Cela ne fonctionne pas pour moi. – Kvothe

+0

D'autres suggestions? – Kvothe

+0

Cher @Kvothe, quand quelqu'un passe du temps à m'aider et à signaler une erreur dans mon code, je dis quelque chose comme "Merci pour votre aide, et j'ai corrigé l'erreur que vous avez signalée", et ensuite, si mon code n'est toujours pas travailler comme je m'attends, je dirais "Bien que, mon code a encore des erreurs supplémentaires, car maintenant ont le comportement suivant ... Pouvez-vous s'il vous plaît m'aider à les trouver?". J'attendrai une appréciation appropriée pour trouver une erreur grossière, avant de passer plus de temps à regarder votre code, et je crois que vous découvrirez que peu de gens passeront du temps à vous aider, si vous ne montrez pas d'appréciation. – Luis

Questions connexes