从SQLite添加要映射的标记,并在zoom(Android)中居中/调整它们

从SQLite添加要映射的标记,并在zoom(Android)中居中/调整它们,android,sqlite,google-maps,google-maps-markers,Android,Sqlite,Google Maps,Google Maps Markers,我真的需要帮助填充从我的数据库中存储的坐标标记地图。我已经从SQLite填充了ListView,我可以向地图添加标记,但我不知道如何从SQLite数据库添加标记。此外,如果我能得到一些帮助,使屏幕上的标记居中并放大到它们都适合的位置,那将是非常棒的!以下是我目前的代码: *更新代码* ALLMAP活性 public class allmapactivity extends MapActivity { GeoPoint GeoP; MapView mapV; private SQLiteAdapt

我真的需要帮助填充从我的数据库中存储的坐标标记地图。我已经从SQLite填充了ListView,我可以向地图添加标记,但我不知道如何从SQLite数据库添加标记。此外,如果我能得到一些帮助,使屏幕上的标记居中并放大到它们都适合的位置,那将是非常棒的!以下是我目前的代码:

*更新代码*

ALLMAP活性

public class allmapactivity extends MapActivity {
GeoPoint GeoP;
MapView mapV;
private SQLiteAdapter mySQLiteAdapter;
public ArrayList<Integer> latitude = new ArrayList<Integer>();
public ArrayList<Integer> longitude = new ArrayList<Integer>();

@Override
protected void onCreate(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onCreate(savedInstanceState);
 setContentView(R.layout.map);
 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
 requestWindowFeature(Window.FEATURE_NO_TITLE);


 mapV = (MapView) findViewById(R.id.mapview);
 mapV.displayZoomControls(true);
 mapV.setBuiltInZoomControls(true);
 mapV.setSatellite(false);

final MapController mController = mapV.getController();

List<Overlay> mapOverlays = mapV.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.pin);

mySQLiteAdapter = new SQLiteAdapter(getApplicationContext());

if(!mySQLiteAdapter.isEmpty())
{
Cursor initcursor = mySQLiteAdapter.queueAll5();
initcursor.moveToFirst();
for(int i = 0; i < initcursor.getCount();i++)
{
    HelloItemizedOverlay itemizedoverlay = 
             new HelloItemizedOverlay(drawable, allmapactivity.this);
    int lat = (int) (initcursor.getDouble(initcursor.getColumnIndex("Content11")) * 1E6);
    int lon = (int) (initcursor.getDouble(initcursor.getColumnIndex("Content12")) * 1E6);
        latitude.add(lat);
        longitude.add(lon);
    GeoPoint geopoint = new GeoPoint(lat, lon);
    String savedtitle = initcursor.getString(initcursor.getColumnIndex("Content9"));
    String savedtext = initcursor.getString(initcursor.getColumnIndex("Content10"));
     OverlayItem overlayitem = new OverlayItem(geopoint, savedtitle, savedtext);
     itemizedoverlay.addOverlay(overlayitem);
     mapOverlays.add(itemizedoverlay);
     initcursor.moveToNext();
  }
  }

        int latSum = 0;
double latAverage = 0;

 for(Integer latitudeValue: latitude)
 {
  latSum = latSum + latitudeValue;
 }

 latAverage = (double) latSum/latitude.size();


 int lonSum = 0;
 double lonAverage = 0;

for(Integer longitudeValue: longitude)
{
 lonSum = lonSum + longitudeValue;
}

lonAverage = (double) lonSum/longitude.size();

    GeoPoint center = new GeoPoint((int) latAverage, (int) lonAverage);

    mController.animateTo(center); 


}

@Override
protected boolean isRouteDisplayed() {

   // TODO Auto-generated method stub

return false;
}

}
不幸的是,我得到了这个代码的强制关闭错误:(这里是logcat:

07-22 19:14:33.918: E/AndroidRuntime(1330): FATAL EXCEPTION: main
07-22 19:14:33.918: E/AndroidRuntime(1330): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.inn.footprint/com.inn.footprint.allmapactivity}: android.util.AndroidRuntimeException: requestFeature() must be called before adding content
07-22 19:14:33.918: E/AndroidRuntime(1330):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at android.os.Looper.loop(Looper.java:130)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at android.app.ActivityThread.main(ActivityThread.java:3683)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at java.lang.reflect.Method.invokeNative(Native Method)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at java.lang.reflect.Method.invoke(Method.java:507)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at dalvik.system.NativeStart.main(Native Method)
07-22 19:14:33.918: E/AndroidRuntime(1330): Caused by: android.util.AndroidRuntimeException: requestFeature() must be called before adding content
07-22 19:14:33.918: E/AndroidRuntime(1330):     at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:181)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at android.app.Activity.requestWindowFeature(Activity.java:2729)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at com.inn.footprint.allmapactivity.onCreate(allmapactivity.java:36)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
07-22 19:14:33.918: E/AndroidRuntime(1330):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
07-22 19:14:33.918: E/AndroidRuntime(1330):     ... 11 more

下面的NotesBadapter改编自developer.android.com上的Notepad教程,可以将其视为数据库包装器。我添加了额外的字段,如lat、lon,它们将成为主键,即如何访问标记的位置,标记将存储在何处。然后,根据这段代码,我还提供了一个修改的请访问您的类allmapactivity,它获取数据库中的所有“注释”,即标记,然后用它们填充您的地图。此代码肯定会工作,因为我已经对其进行了测试!如果您需要进一步的建议,请告诉我

干杯

/*
* Copyright (C) 2008 Google Inc.
* 
* 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.
*/


import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
* Simple notes database access helper class. Defines the basic CRUD operations
* for the notepad example, and gives the ability to list all notes as well as
* retrieve or modify a specific note.
* 
* This has been improved from the first version of this tutorial through the
* addition of better error handling and also using returning a Cursor instead
* of using a collection of inner classes (which is less scalable and not
* recommended).
*/
public class NotesDbAdapter {

public static final String KEY_TITLE = "title";
public static final String KEY_BODY = "body";
public static final String KEY_LAT = "lat";
public static final String KEY_LON = "lon";

private static final String TAG = "NotesDbAdapter";
public DatabaseHelper mDbHelper;
public SQLiteDatabase mDb;

/**
 * Database creation sql statement
 */
private static final String DATABASE_CREATE =
    "CREATE TABLE notes (lat REAL, lon REAL, title varchar(60), body varchar(300), PRIMARY KEY (lat, lon));";

private static final String DATABASE_NAME = "data";
private static final String DATABASE_TABLE = "notes";
private static final int DATABASE_VERSION = 2;

private final Context mCtx;

private static class DatabaseHelper extends SQLiteOpenHelper {

    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL(DATABASE_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS notes");
        onCreate(db);
    }
}

/**
 * Constructor - takes the context to allow the database to be
 * opened/created
 * 
 * @param ctx the Context within which to work
 */
public NotesDbAdapter(Context ctx) {
    this.mCtx = ctx;
    open();
}

/**
 * Open the notes database. If it cannot be opened, try to create a new
 * instance of the database. If it cannot be created, throw an exception to
 * signal the failure
 * 
 * @return this (self reference, allowing this to be chained in an
 *         initialization call)
 * @throws SQLException if the database could be neither opened or created
 */
public NotesDbAdapter open() throws SQLException {
    mDbHelper = new DatabaseHelper(mCtx);
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

public void close() {
    mDbHelper.close();
}


/**
 * Create a new note using the title and body provided. If the note is
 * successfully created return the new rowId for that note, otherwise return
 * a -1 to indicate failure.
 * 
 * @param title the title of the note
 * @param body the body of the note
 * @return rowId or -1 if failed
 */
public long createNote(double lat, double lon, String title, String body) {
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_LAT, lat);
    initialValues.put(KEY_LON, lon);
    initialValues.put(KEY_TITLE, title);
    initialValues.put(KEY_BODY, body);

    return mDb.insert(DATABASE_TABLE, null, initialValues);
}

/**
 * Delete the note with the given rowId
 * 
 * @param rowId id of note to delete
 * @return true if deleted, false otherwise
 */
public boolean deleteNote(double lat, double lon) {

    return mDb.delete(DATABASE_TABLE, KEY_LAT + "=" + lat + " and " + KEY_LON + "=" + lon, null) > 0;
}

/**
 * Return a Cursor over the list of all notes in the database
 * 
 * @return Cursor over all notes
 */
public Cursor fetchAllNotes() {
    return mDb.query("notes", new String[] {KEY_LAT, KEY_LON,
            KEY_TITLE, KEY_BODY}, null, null, null, null, null);
}

/**
 * Return a Cursor positioned at the note that matches the given rowId
 * 
 * @param rowId id of note to retrieve
 * @return Cursor positioned to matching note, if found
 * @throws SQLException if note could not be found/retrieved
 */
public Cursor fetchNote(double lat, double lon) {

    try{    
    Cursor mCursor =

        mDb.query(true, DATABASE_TABLE, new String[] {KEY_LAT, KEY_LON,
                KEY_TITLE, KEY_BODY}, KEY_LAT + "=" + lat+ " and "+KEY_LON+"="+lon, null,
                null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
    }
    catch(SQLException sqle)
    {
        return null;
    }
}

/**
 * Update the note using the details provided. The note to be updated is
 * specified using the rowId, and it is altered to use the title and body
 * values passed in
 * 
 * @param rowId id of note to update
 * @param title value to set note title to
 * @param body value to set note body to
 * @return true if the note was successfully updated, false otherwise
 */
public boolean updateNote(double lat, double lon, String title, String body) {
    ContentValues args = new ContentValues();
    args.put(KEY_TITLE, title);
    args.put(KEY_BODY, body);

    return mDb.update(DATABASE_TABLE, args, KEY_LAT + "=" + lat + " and " + KEY_LON + "=" + lon, null) > 0;
}

public boolean isEmpty()
{
    try{
    Cursor check = mDb.query("notes", new String[] {"lat"}, null, null, null, null, null);
    }
    catch(NullPointerException e)
    {
        return true;
    }
    return false;
}
}
-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/

public class allmapactivity extends MapActivity {
MapController mControl;
GeoPoint GeoP;
MapView mapV;
Cursor cursor;
private NotesDbAdapter mDbHelper;
public ArrayList<Integer> latitude = new ArrayList<Integer>();
public ArrayList<Integer> longitude = new ArrayList<Integer>();

@Override
protected void onCreate(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onCreate(savedInstanceState);
 setContentView(R.layout.map);
 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);


 mapV = (MapView) findViewById(R.id.mapview);
 mapV.displayZoomControls(true);
 mapV.setBuiltInZoomControls(true);
 mapV.setSatellite(false);

final MapController mController = mapV.getController();

List<Overlay> mapOverlays = mapV.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.pin);

mDbHelper = new NotesDbAdapter(getApplicationContext());

    if(!mDbHelper.isEmpty())
    {
    Cursor initcursor = mDbHelper.fetchAllNotes();
    initcursor.moveToFirst();
    for(int i = 0; i < initcursor.getCount();i++)
    {
        HelloItemizedOverlay itemizedoverlay = 
                 new HelloItemizedOverlay(drawable, allmapactivity.this);
        int lat = (int) (initcursor.getDouble(initcursor.getColumnIndex("lat")) * 1E6);
        int lon = (int) (initcursor.getDouble(initcursor.getColumnIndex("lon")) * 1E6);
            latitude.add(lat);
            longitude.add(lon);
        GeoPoint geopoint = new GeoPoint(lat, lon);
        String savedtitle = initcursor.getString(initcursor.getColumnIndex("title");
        String savedtext = initcursor.getString(initcursor.getColumnIndex("body"));
         OverlayItem overlayitem = new OverlayItem(geopoint, savedtitle, savedtext);
         itemizedoverlay.addOverlay(overlayitem);
         mapOverlays.add(itemizedoverlay);
         initcursor.moveToNext();
    }
    }

        String mapCenter = getMapCenter(latitude, longitude);
        int latCenter = (int) (mapCenter.split(",")[0] * 1E6);
        int lonCenter = (int) (mapCenter.split(",")[1] * 1E6);
        GeoPoint center = new GeoPoint(latCenter, lonCenter);

        mController.animateTo(center); // This will move the map focus to the central point of the markers found in the function getMapCenter();



}


 public String getMapCenter(ArrayList<Integer> latitudeList, ArrayList<Integer> longitudeList)
 {
  // This function, as the name suggests will return the latitude, longitude of the central point of the markers found by taking the average of the latitude and longitude values of the markers
  int latSum = 0;
  int lonSum = 0;
  double latAverage = 0;
  double lonAverage = 0;
  String result;

 for(Integer latitudeValue: latitudeList)
 {
  latSum = latSum + latitudeValue;
 }
 for(Integer longitudeValue: longitudeList)
 {
  lonSum = lonSum + longitudeValue;
 }

 latAverage = (double) latSum/latitudeList.size();
 lonAverage = (double) lonSum/longitudeList.size();

 result = latAverage+","+lonAverage;
 return result;
}

@Override
protected boolean isRouteDisplayed() {

   // TODO Auto-generated method stub

return false;
}

}
现在,您的类allmapactivity的代码是:

-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/

public class allmapactivity extends MapActivity {
MapController mControl;
GeoPoint GeoP;
MapView mapV;
Cursor cursor;
private NotesDbAdapter mDbHelper;
public ArrayList<Integer> latitude = new ArrayList<Integer>();
public ArrayList<Integer> longitude = new ArrayList<Integer>();

@Override
protected void onCreate(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onCreate(savedInstanceState);
 setContentView(R.layout.map);
 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);


 mapV = (MapView) findViewById(R.id.mapview);
 mapV.displayZoomControls(true);
 mapV.setBuiltInZoomControls(true);
 mapV.setSatellite(false);

final MapController mController = mapV.getController();

List<Overlay> mapOverlays = mapV.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.pin);

mDbHelper = new NotesDbAdapter(getApplicationContext());

    if(!mDbHelper.isEmpty())
    {
    Cursor initcursor = mDbHelper.fetchAllNotes();
    initcursor.moveToFirst();
    for(int i = 0; i < initcursor.getCount();i++)
    {
        HelloItemizedOverlay itemizedoverlay = 
                 new HelloItemizedOverlay(drawable, allmapactivity.this);
        int lat = (int) (initcursor.getDouble(initcursor.getColumnIndex("lat")) * 1E6);
        int lon = (int) (initcursor.getDouble(initcursor.getColumnIndex("lon")) * 1E6);
            latitude.add(lat);
            longitude.add(lon);
        GeoPoint geopoint = new GeoPoint(lat, lon);
        String savedtitle = initcursor.getString(initcursor.getColumnIndex("title");
        String savedtext = initcursor.getString(initcursor.getColumnIndex("body"));
         OverlayItem overlayitem = new OverlayItem(geopoint, savedtitle, savedtext);
         itemizedoverlay.addOverlay(overlayitem);
         mapOverlays.add(itemizedoverlay);
         initcursor.moveToNext();
    }
    }

        String mapCenter = getMapCenter(latitude, longitude);
        int latCenter = (int) (mapCenter.split(",")[0] * 1E6);
        int lonCenter = (int) (mapCenter.split(",")[1] * 1E6);
        GeoPoint center = new GeoPoint(latCenter, lonCenter);

        mController.animateTo(center); // This will move the map focus to the central point of the markers found in the function getMapCenter();



}


 public String getMapCenter(ArrayList<Integer> latitudeList, ArrayList<Integer> longitudeList)
 {
  // This function, as the name suggests will return the latitude, longitude of the central point of the markers found by taking the average of the latitude and longitude values of the markers
  int latSum = 0;
  int lonSum = 0;
  double latAverage = 0;
  double lonAverage = 0;
  String result;

 for(Integer latitudeValue: latitudeList)
 {
  latSum = latSum + latitudeValue;
 }
 for(Integer longitudeValue: longitudeList)
 {
  lonSum = lonSum + longitudeValue;
 }

 latAverage = (double) latSum/latitudeList.size();
 lonAverage = (double) lonSum/longitudeList.size();

 result = latAverage+","+lonAverage;
 return result;
}

@Override
protected boolean isRouteDisplayed() {

   // TODO Auto-generated method stub

return false;
}

}
公共类allmapactivity扩展了MapActivity{
地图控制器;
地质点;
MapView mapV;
光标;
私人票据登记簿;
公共ArrayList纬度=新ArrayList();
公共ArrayList经度=新ArrayList();
@凌驾
创建时受保护的void(Bundle savedInstanceState){
//TODO自动生成的方法存根
super.onCreate(savedInstanceState);
setContentView(R.layout.map);
setRequestedOrientation(ActivityInfo.SCREEN\u ORIENTATION\u Picture);
mapV=(MapView)findviewbyd(R.id.MapView);
mapV.displayZoomControl(真);
mapV.setBuiltInZoomControls(真);
mapV.setSatellite(假);
最终映射控制器mController=mapV.getController();
List mapOverlays=mapV.getOverlays();
Drawable Drawable=this.getResources().getDrawable(R.Drawable.pin);
mDbHelper=newnotesdbadapter(getApplicationContext());
如果(!mDbHelper.isEmpty())
{
Cursor initcursor=mDbHelper.fetchAllNotes();
initcursor.moveToFirst();
对于(int i=0;i
我已将您的代码放入我的代码中,并一直存在强制关闭问题:(请看上面更新的帖子。我在“content11”中存储我的纬度,在“content12”中存储我的经度。顺便说一句,谢谢你帮助我做到这一点,你非常擅长这一点!@user1526003请检查我对你编辑的问题的评论,因为它包含解决方案:)问题的解决方案是:在调用setContentView(R.layout.map)之前,必须调用requestWindowFeature(Window.FEATURE\u NO\u TITLE);这是因为窗口功能(FEATURE\u NO\u TITLE)实际上是视图的一部分,因此应用程序必须事先知道视图不会有标题。因此解决方案是:super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE\u NO\u title);setContentView(R.layout.map);setRequestedOrientation(ActivityInfo.SCREEN\u ORIENTATION\u Grait);哇…我不知道。谢谢。现在一切都很好,我的地图加载并平移到中心,但是没有显示点。我认为加载点是个问题,因为即使我的数据库中有坐标,它也总是以非洲为中心,没有显示点。我觉得我又犯了一个愚蠢的错误。很高兴听到这个消息!如果你如果您觉得我已经回答了您的问题,您应该接受我在下面给出的答案。您可以通过单击我答案左上角的绿色小箭头来执行此操作!如果您可以,我将不胜感激:)我建议您使用日志调试程序。在for循环中执行此操作