Google映射API v2 Android,而不是在离线时绘制多边形

时间:2013-02-01 11:16:19

标签: google-maps-android-api-2 offline-caching

我有一个测试应用程序,我使用谷歌地图API绘制一个多边形。

问题在于,当我没有任何地图的缓存(新安装的应用程序)时,Polygon不会绘制。 没有加载地图不是问题,但我需要在屏幕上绘制多边形。 我有办法做到吗?

我的英语不好

继承我的代码:

package ngvl.testegmaps_v2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import ngvl.testegmaps_v2.VO.GeoPosicionamento;
import ngvl.testegmaps_v2.VO.Layer;
import ngvl.testegmaps_v2.VO.Secao;
import ngvl.testegmaps_v2.VO.Talhao;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class MainActivity extends FragmentActivity {

    private List<Secao> secoes;
    private List<Polygon> poligonos = new ArrayList<Polygon>();

    private HashMap<String,Object[]>  informacoes  = new HashMap<String,Object[]>();

    private GoogleMap map;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);

        map = fragment.getMap();

        map.getUiSettings().setRotateGesturesEnabled(false);

        // Setting a click event handler for the map

        LatLng latLng = new LatLng(-20.9957152, -47.3241304);
        // map.addMarker(new
        // MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)).title("Av. Paulista").snippet("São Paulo"));

        configuraPosicao(map, latLng);

        Button button = (Button)findViewById(R.id.button1);
        // Register the onClick listener with the implementation above
        button.setOnClickListener(mCorkyListener);

    }

    private void configuraPosicao(GoogleMap map, LatLng latLng) {

        /*
         * 3D map.moveCamera( CameraUpdateFactory.newLatLngZoom(latLng, 15));
         * map.animateCamera( CameraUpdateFactory.zoomTo(10), 2000, null);
         * 
         * CameraPosition cameraPosition = new CameraPosition.Builder()
         * .target(latLng) .zoom(17) .bearing(90) .tilt(45) .build();
         * 
         * map.animateCamera( CameraUpdateFactory.newCameraPosition(
         * cameraPosition));
         */
        map.setMapType(GoogleMap.MAP_TYPE_NONE);
        // map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17.0f));
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));

        try {

            String json = readFileAsString("geo.json");

            Gson gson = new Gson();
            this.secoes = gson.fromJson(json, new TypeToken<List<Secao>>() {
            }.getType());
            json = null;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        escrevePoligons(map);

    }

    private String readFileAsString(String fileName) throws IOException {
        InputStream is = getAssets().open(fileName);
        if (is != null) {
            StringBuilder sb = new StringBuilder();
            String line;

            try {
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is, "UTF-8"));
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append("\n");
                }
            } finally {
                is.close();
            }
            return sb.toString();
        } else {
            return "";
        }
    }

    private void escrevePoligons(GoogleMap map) {

        float stroke = (float) 1.5;

        for (Secao secao : secoes) {
            for (Talhao talhao : secao.getTalhoes()) {
                for (Layer layer : talhao.getLayers()) {

                    // PolygonOptions rectOptions = new PolygonOptions();
                    List<LatLng> latlngs = new ArrayList<LatLng>();

                    for (GeoPosicionamento geoPosicionamento : layer.getGeoPosicionamentos()) {

                        latlngs.add(new LatLng(geoPosicionamento.getLatitude()
                                .setScale(7, BigDecimal.ROUND_HALF_EVEN)
                                .doubleValue(), geoPosicionamento
                                .getLongitude()
                                .setScale(7, BigDecimal.ROUND_HALF_EVEN)
                                .doubleValue()));
                    }

                    int color = 0x1F00FF00;
                    int color2 = 0x5F000000;

                    PolygonOptions polygonOptions = new PolygonOptions()
                                                        .fillColor(color).addAll(latlngs)
                                                        .strokeColor(color2).strokeWidth(stroke);

                    Polygon p = map.addPolygon(polygonOptions);

                    poligonos.add(p);

                    informacoes.put( p.getId(), new Object[]{ secao, talhao , layer } );

                    //System.out.println(polygonOptions.getPoints());

                    polygonOptions = null;
                    latlngs = null;
                }
            }
        }
        this.secoes = null;

        // String mUrl =
        // "https://khms0.google.com.br/kh/v=124&src=app&z={z}&x={x}&y={y}";
        // MyUrlTileProvider mTileProvider = new MyUrlTileProvider(256, 256,
        // mUrl);
        // mTileProvider.tilesRange();
        // map.addTileOverlay(new
        // TileOverlayOptions().tileProvider(mTileProvider).zIndex(-1f));

        //String mUrl = "http://a.tile.openstreetmap.org/{z}/{x}/{y}.png";
        //MyUrlTileProvider mTileProvider = new MyUrlTileProvider(256, 256, mUrl);
        //map.addTileOverlay(new TileOverlayOptions().tileProvider(mTileProvider).zIndex(-1f));

        map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-20.9957152, -47.3241304), 14));

        // TileProvider tileProvider = TileProviderFactory.getTileProvider();
        // map.addTileOverlay(new
        // TileOverlayOptions().tileProvider(tileProvider));
        // map.moveCamera(CameraUpdateFactory.newLatLngZoom(new
        // LatLng(-20.9957152, -47.3241304), 15));

        map.setOnMapClickListener(new OnMapClickListener() 
        {
            public void onMapClick(LatLng point) 
            {
                Polygon p = isPointInPolygon(point);

                if( p != null){

                    p.setFillColor(getRandomColor());

                    Object[] clicado = informacoes.get( p.getId() );

                    Secao  secao_clicada  = (Secao)  clicado[0];
                    Talhao talhao_clicada = (Talhao) clicado[1];
                    Layer  layer_clicada  = (Layer)  clicado[2];

                    //System.out.println(secao_clicada);                    
                    //System.out.println(talhao_clicada);
                    //System.out.println(layer_clicada);
                    //System.out.println("=======================");

                    StringBuilder texto = new StringBuilder();
                    texto.append("Seção: " + secao_clicada.getDesc() + "\n");
                    texto.append("Talhão: " + talhao_clicada.getTalhao() + "\n");
                    texto.append("Variedade: " + talhao_clicada.getVariedade() + " - " + talhao_clicada.getDescVariedade() + "\n");
                    texto.append("Layer: " + layer_clicada.getSequencia() + "\n");

                    //Toast.makeText(MainActivity.this, texto , Toast.LENGTH_LONG).show();

                    addMarker(point,texto);

                }//else
                    //Toast.makeText(MainActivity.this,"Clicou fora da Área de um Poligono", Toast.LENGTH_LONG).show();
            }    
         });

    }

    public void addMarker(LatLng point, StringBuilder texto) {

        /*map.addMarker(new MarkerOptions().position(point).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))
                                         .title("Caracteristicas: ")
                                         .snippet( texto );
                                         */
        Toast.makeText(MainActivity.this, texto , Toast.LENGTH_LONG).show();

    }

    private Polygon isPointInPolygon(LatLng tap) {


        for( Polygon p  : poligonos){
            int intersectCount = 0;
            List<LatLng> vertices = p.getPoints();

            for(int j=0; j<vertices.size()-1; j++) {
                if( rayCastIntersect(tap, vertices.get(j), vertices.get(j+1)) ) {
                    intersectCount++;
                }
            }

            if(((intersectCount % 2) == 1)){
                return p;
            }

        }

        return  null;// odd = inside, even = outside;
    }

    private boolean rayCastIntersect(LatLng tap, LatLng vertA, LatLng vertB) {

         double aY = vertA.latitude;
            double bY = vertB.latitude;
            double aX = vertA.longitude;
            double bX = vertB.longitude;
            double pY = tap.latitude;
            double pX = tap.longitude;

            if ( (aY>pY && bY>pY) || (aY<pY && bY<pY) || (aX<pX && bX<pX) ) {
                return false; // a and b can't both be above or below pt.y, and a or b must be east of pt.x
            }

            double m = (aY-bY) / (aX-bX);               // Rise over run
            double bee = (-aX) * m + aY;                // y = mx + b
            double x = (pY - bee) / m;                  // algebra is neat!

            return x > pX;
    }

    private OnClickListener mCorkyListener = new OnClickListener() {
        public void onClick(View v) {
          // do something when the button is clicked

            map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-20.9957152, -47.3241304), 14));

        }
    };

    public int getRandomColor() {
        int color;
        Random rnd = new Random();
        color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256),
                rnd.nextInt(256));
        return color;
    }

}

如上例所示,将地图类型设置为MAP_TYPE_NONE无法解决问题

2 个答案:

答案 0 :(得分:1)

我将使用Maps Forge Open Source API标记为已解决 如果有人使用谷歌地图Api请分享,我会改变答案。

我找到的答案是,如果不先渲染地图(在线或通过缓存),就无法渲染或访问任何内容

答案 1 :(得分:1)

这实际上是适用于Android的GoogleMaps Api v2的错误。

这里引用: https://code.google.com/p/gmaps-api-issues/issues/detail?id=5017

如果你想加速错误修复,请加注星标!