2011-03-22 2 views
4

google 맵 패키지를 사용하여 포인트가 오프셋 된 이상한 문제가 발생했습니다.MapView를 최대 줌 레벨로 패닝 할 때 GeoPoint 및/또는 android.maps의 이상한 동작

경로가 표시된 MapView가 있습니다. 모든 경로를 확대/축소 한 다음 이동하면 경로가 창 가장자리 근처에서 잘리는 것으로 나타났습니다. 이 픽셀을 번역 MapView.getProjection (에 의해 반환 된 프로젝션 클래스)를 사용

  GeoPoint midPoint = projection.fromPixels(mapView.getWidth()/2, mapView.getHeight()/2); 
      GeoPoint nextPoint = new GeoPoint(midPoint.getLatitudeE6(), midPoint.getLongitudeE6()); 
      pathPaint.setColor(0xFF00FF00); 
      projection.toPixels(midPoint, screenPoint); 
      canvas.drawCircle(screenPoint.x, screenPoint.y, 5, pathPaint); 
      pathPaint.setColor(0xFF0000FF); 
      projection.toPixels(nextPoint, screenPoint); 
      canvas.drawCircle(screenPoint.x, screenPoint.y, 5, pathPaint); 

GeoPoint의에 좌표 : 내 자신의 코드의 많은 디버깅 후,이 같은 심지어 간단한 경우이 문제를 repro 수에 충분했다 발견 . 그런 다음 동일한 위도/경도를 사용하여 두 번째 GeoPoint를 만듭니다. 마지막으로이 GeoPoints를 모두 화면 좌표로 변환하고이 위치에서 다른 하나의 상단에 두 개의 원을 그립니다.

제외하고 두 번째 원은 첫 번째 원에서 오프셋됩니다. 그것들은 동일한 위도/경도 좌표 (그림을 확인)를 가지지 만 다른 화면 좌표로 변환되게됩니다. 내 디버깅은 수평으로 패닝에 초점을 맞추고 있지만 수직으로 패닝하면 원래의 앱 코드에서 보았던 것을 기반으로 비슷한 문제가 발생할 수 있다고 생각합니다.

필자가 말할 수있는 한, 맵 패키지에 의해 만들어진 모든 포인트는 정상적으로 작동하지만 새로운 GeoPoint (lat, lon)를 호출하여 생성 된 포인트는이 동작을 나타냅니다.

아래에 붙여 넣은 간단한 동작 제거 응용 프로그램을 만들었습니다. (지도 타일은 서명하기가 번거롭기 때문에 다운로드되지 않지만 문제를 보지 않아도됩니다.) 시작하고 좌우로 확대하여 왼쪽 또는 오른쪽으로 이동합니다. 녹색과 파란색 점이 엇갈리는 것을 관찰하고 Log.d 인쇄물이 여전히 동일한 위도/경도를 유지하고 있음을 확인하십시오.

(샘플 프로젝트를 올리기위한 더 나은/선호하는 방법이 있나요 죄송합니다,이 내 첫 포스팅은 여기에있다?.)

SRC/예/mysample이/MapOverlay.java :

package example.mysample; 

import java.util.ArrayList; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Point; 
import android.graphics.Color; 
import android.graphics.DashPathEffect; 
import android.graphics.RadialGradient; 
import android.graphics.Shader; 
import android.view.MotionEvent; 

import com.google.android.maps.GeoPoint; 
import com.google.android.maps.MapView; 
import com.google.android.maps.Overlay; 
import com.google.android.maps.Projection; 

import android.util.Log; 

class MapOverlay extends Overlay 
{ 
    public MapOverlay(MapScreen activity) 
    { 
     super(); 

     paint = new Paint(); 
     paint.setStyle(Paint.Style.FILL_AND_STROKE); 
     paint.setAntiAlias(true); 
    } 

    @Override public boolean onTouchEvent(MotionEvent e, MapView mapView) { 
     int motionAction = e.getAction(); 
     if (motionAction == MotionEvent.ACTION_MOVE) { 
      dragging = true; 
     } 
     if (motionAction == MotionEvent.ACTION_UP || motionAction == MotionEvent.ACTION_CANCEL) { 
      dragging = false; 
     } 
     return super.onTouchEvent(e, mapView); 
    } 

    @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { 
     if (!shadow && !dragging) { 
      Projection projection = mapView.getProjection(); 

      // Draw two circles at the center 
      // One with a virgin point, one that we constructed with the same coordinates 
      GeoPoint midPoint = projection.fromPixels(mapView.getWidth()/2, mapView.getHeight()/2); 
      GeoPoint nextPoint = new GeoPoint(midPoint.getLatitudeE6(), midPoint.getLongitudeE6()); 
      paint.setColor(0xFF00FF00); 
      projection.toPixels(midPoint, screenPoint); 
      canvas.drawCircle(screenPoint.x, screenPoint.y, 5, paint); 
      paint.setColor(0xFF0000FF); 
      projection.toPixels(nextPoint, screenPoint); 
      canvas.drawCircle(screenPoint.x, screenPoint.y, 5, paint); 

      // These print EQUAL. 
      Log.d("BKC DEBUG", "Midpoint and our own midpoint have " + 
       ((midPoint.getLatitudeE6() == nextPoint.getLatitudeE6()) ? "EQUAL" : "UNEQUAL") + 
       " latitudes, and " + 
       ((midPoint.getLongitudeE6() == nextPoint.getLongitudeE6()) ? "EQUAL" : "UNEQUAL") + 
       " longitudes"); 
     } 
    } 

    private Paint paint; 
    private boolean dragging; 
    private Point screenPoint = new Point(); 

} 

SRC/예/mysample이/MapScreen.java :

package example.mysample; 

import android.os.Bundle; 
import android.view.View; 
import android.widget.Toast; 
import android.util.Log; 

import com.google.android.maps.MapActivity; 
import com.google.android.maps.MapController; 
import com.google.android.maps.MapView; 
import com.google.android.maps.GeoPoint; 

public class MapScreen extends MapActivity 
{ 

    @Override public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 
     setContentView(R.layout.map); 

     mapView = (MapView)findViewById(R.id.map_map); 
     mapView.setBuiltInZoomControls(true); 
     mapView.getOverlays().add(new MapOverlay(this)); 

     MapController controller; 
     controller = mapView.getController(); 
     controller.setZoom(17); 
     controller.animateTo(new GeoPoint(36000000, -90000000)); 

    } 

    @Override 
    public boolean isRouteDisplayed() { 
     return true; 
    } 

    private MapView mapView; 

} 

입술/레이아웃/map.xml :

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#414141" 
    >  

<com.google.android.maps.MapView 
      android:id="@+id/map_map" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:layout_marginLeft="3dip" 
      android:layout_marginRight="3dip" 
      android:layout_marginTop="3dip" 
      android:layout_marginBottom="3dip" 
      android:apiKey="0jPQdwUtQGBYfPALki6ghGG_X9Jpf-SllYckR4w" 
      android:layout_centerInParent="true" 
      android:clickable="true" 
      /> 

</RelativeLayout> 
(템플릿에서 변경)

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="example.mysample" 
     android:versionCode="1" 
     android:versionName="2.0.1"> 
    <uses-sdk android:minSdkVersion="4" /> 

    <!--uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /--> 
    <!--uses-permission android:name="android.permission.READ_PHONE_STATE" /--> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <!--uses-permission android:name="android.permission.WAKE_LOCK" /--> 
    <!--uses-permission android:name="android.permission.READ_LOGS" /--> 
    <!--uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /--> 

    <!--application android:name="src.example.mysample.AppMain" 
       android:label="MySample" 
       android:icon="@drawable/icon_android" 
       android:theme="@android:style/Theme.NoTitleBar" 
       --> 

    <application android:name="android.app.Application" 
     android:label="MySample" > 

     <uses-library android:name="com.google.android.maps"/> 

     <!-- Main activity --> 
     <activity android:name="example.mysample.MapScreen" 
        android:clearTaskOnLaunch="true" 
        android:label="MySample" 
        android:screenOrientation="portrait"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <!-- Other activities --> 
     <!--activity android:name="example.mysample.SomethingElse" 
        android:label="Something" 
        android:screenOrientation="portrait"/--> 

    </application> 
</manifest> 

의 build.xml :개

의 AndroidManifest.xml 나는이 문제에 직면하고있다

<?xml version="1.0" encoding="UTF-8"?> 
<project name="PROJECT_NAME" default="help"> 

<!-- The local.properties file is created and updated by the 'android' 
    tool. 
    It contains the path to the SDK. It should *NOT* be checked into 
    Version Control Systems. --> 
    <property file="local.properties" /> 

    <!-- The build.properties file can be created by you and is never touched 
     by the 'android' tool. This is the place to change some of the 
     default property values used by the Ant rules. 
     Here are some properties you may want to change/update: 

     source.dir 
      The name of the source directory. Default is 'src'. 
     out.dir 
      The name of the output directory. Default is 'bin'. 

     Properties related to the SDK location or the project target should 
     be updated using the 'android' tool with the 'update' action. 

     This file is an integral part of the build system for your 
     application and should be checked into Version Control Systems. 

     --> 
    <property file="build.properties" /> 

    <!-- The default.properties file is created and updated by the 'android' 
     tool, as well as ADT. 
     This file is an integral part of the build system for your 
     application and should be checked into Version Control Systems. --> 
    <property file="default.properties" /> 

    <!-- Custom Android task to deal with the project target, and import the 
     proper rules. 
     This requires ant 1.6.0 or above. --> 
    <path id="android.antlibs"> 
     <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" /> 
     <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" /> 
     <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" /> 
    </path> 

    <taskdef name="setup" 
     classname="com.android.ant.SetupTask" 
     classpathref="android.antlibs" /> 

<!-- extension targets. Uncomment the ones where you want to do custom work 
    in between standard targets --> 
<!-- 
    <target name="-pre-build"> 
    </target> 
    <target name="-pre-compile"> 
    </target> 

    [This is typically used for code obfuscation. 
    Compiled code location: ${out.classes.absolute.dir} 
    If this is not done in place, override ${out.dex.input.absolute.dir}] 
    <target name="-post-compile"> 
    </target> 
--> 


    <!-- Execute the Android Setup task that will setup some properties 
     specific to the target, and import the build rules files. 

     The rules file is imported from 
      <SDK>/platforms/<target_platform>/ant/ant_rules_r#.xml 

     To customize existing targets, there are two options: 
     - Customize only one target: 
      - copy/paste the target into this file, *before* the 
       <setup> task. 
      - customize it to your needs. 
     - Customize the whole script. 
      - copy/paste the content of the rules files (minus the top node) 
       into this file, *after* the <setup> task 
      - disable the import of the rules by changing the setup task 
       below to <setup import="false" />. 
      - customize to your needs. 
    --> 
    <setup /> 

</project> 
+0

나는 누구에게도이 소리가 들리지 않는다면 듣고 싶습니다. – benkc

답변

1

은 - 안드로이드지도보기 API의 버그 것 같다 - 내가 생각 별 문제는 다음과 같습니다. http://code.google.com/p/android/issues/detail?id=17387&can=5&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars 추한 것 일 수도 있지만 해결 방법은 설명에 포함되어 있습니다. 기본적으로 오류를 확인하고 그에 따라 결과를 조정하십시오.

+0

감사합니다 - 못 생겼지 만 현재로서는 가장 좋은 해결책 인 것 같습니다. – benkc

관련 문제