通过在Android中单击地图OpenStreetMap设置标记

时间:2018-07-20 15:30:26

标签: java c# android xamarin.android

如何在Android或Xamarin.Android中单击地图并在开放的街道地图上添加书签

2 个答案:

答案 0 :(得分:0)

地图活动的XML布局还具有搜索编辑文本,以使用Google地图搜索地点。 地图活动的XML布局应包含

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

    <TextView android:id="@+id/addressTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".AppComponents.Activities.LocationPickerActivity" />

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="4dp"
        android:paddingTop="4dp"
        card_view:cardElevation="4dp"
        card_view:cardMaxElevation="4dp"
        card_view:cardUseCompatPadding="true"
        card_view:cardCornerRadius="4dp">
    <fragment
        android:id="@+id/place_autocomplete_fragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:name="com.google.android.gms.location.places.ui.PlaceAutocompleteFragment"
        />
    </android.support.v7.widget.CardView>

    <Button
        android:id="@+id/locationSetButton"
        android:layout_width="wrap_content"
        android:elevation="8dp"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentStart="true"
        android:layout_marginBottom="17dp"
        android:layout_marginStart="27dp"
        android:text="Set Location" />


</RelativeLayout>

在LocationPicker.java类中,您必须声明Marker&GoogleMap类型的变量。

package com.app1.myapplication.AppComponents.Activities;

import android.app.Activity;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.location.places.ui.PlaceAutocomplete;
import com.google.android.gms.location.places.ui.PlaceAutocompleteFragment;
import com.google.android.gms.location.places.ui.PlacePicker;
import com.google.android.gms.location.places.ui.PlaceSelectionListener;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.app1.myapplication.R;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;

public class LocationPicker extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    Marker markerLocation;
    private GoogleApiClient mGoogleApiClient;
    private FusedLocationProviderClient mFusedLocationClient;
    private LocationRequest mLocationRequest;
    private LocationCallback mLocationCallback;
    double a,b;
    Place place;
    LatLng finalLocation;

    private LatLngBounds.Builder mBounds = new LatLngBounds.Builder();

    private void addPointToViewPort(LatLng newPoint) {
        mBounds.include(newPoint);
        mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(mBounds.build(),
                findViewById(R.id.addressTextView).getHeight()));
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1) {
            if (resultCode == Activity.RESULT_OK) {
                place = PlacePicker.getPlace(this, data);

                PlaceAutocomplete.getPlace(this,data);
            } else if (resultCode == PlacePicker.RESULT_ERROR) {
                Toast.makeText(this, "Places API failure! Check that the API is enabled for your key",
                        Toast.LENGTH_LONG).show();
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
        try {
            Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_OVERLAY).build(this);
            startActivityForResult(intent,1);
        }
        catch (GooglePlayServicesRepairableException e){
        }
        catch (GooglePlayServicesNotAvailableException e){
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_location_picker);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Places.GEO_DATA_API)
                .build();
        mGoogleApiClient.connect();

        View locationButton = ((View) findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
        RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
// position on right bottom
        rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
        rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
        rlp.setMargins(0, 1500, 30, 20);

        PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)
                getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);

        //Task<AutocompletePredictionBufferResponse> results=Places.GeoDataApi.getAutocompletePredictions()
        autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
            @Override
            public void onPlaceSelected(Place place2) {
               place=place2;
               finalLocation=place2.getLatLng();
               mMap.moveCamera(CameraUpdateFactory.newLatLng(place2.getLatLng()));
                mMap.animateCamera(CameraUpdateFactory.zoomTo(17));
                try{
                    mMap.setMyLocationEnabled(true);
                }
                catch(SecurityException e){

                }
                // TODO: Get info about the selected place.
                //Log.i(TAG, "Place: " + place.getName());
            }

            @Override
            public void onError(Status status) {
                // TODO: Handle the error.
                //Log.i(TAG, "An error occurred: " + status);
            }
        });

        Button locationSetButton=(Button)findViewById(R.id.locationSetButton);
        locationSetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                LatLng msd=finalLocation;
                //getCallingActivity();
                Geocoder geocoder=new Geocoder(LocationPickerActivity.this, Locale.getDefault());
                List<Address> nearByList=null;
                try {
                    nearByList = geocoder.getFromLocation(finalLocation.latitude,finalLocation.longitude , 1);
                }
                catch (IOException e){

                }
                Intent intent=new Intent();
                double[] geoCoordinates=new double[2];
                geoCoordinates[0]=msd.latitude;
                geoCoordinates[1]=msd.longitude;

                JSONObject userJSONObject=new JSONObject();
                JSONArray userJSONArray=new JSONArray();
                try {
                    Geocoder geocoder2=new Geocoder(LocationPickerActivity.this, Locale.getDefault());
                    List<Address> nearByList2=null;
                    HashSet<String> ls2=new HashSet<String>();
                    try {
                        nearByList = geocoder.getFromLocation(msd.latitude, msd.longitude, 1);
                    }
                    catch (IOException e){

                    }
                    Address ad2=nearByList.get(0);
                    ls2.add(ad2.getPostalCode());

                    DecimalFormat decimalFormat=new DecimalFormat("#.#####");
                    double x=Double.parseDouble(decimalFormat.format(msd.latitude));
                    double y=Double.parseDouble(decimalFormat.format(msd.longitude));
                    userJSONObject.put("Latitude", x);
                    userJSONObject.put("Longitude", y);
                    userJSONObject.put("GoogleAddressLine",ad2.getAddressLine(0));
                    userJSONObject.put("zipCode",ad2.getPostalCode());
                    userJSONObject.put("city",ad2.getLocality());
                    userJSONObject.put("state",ad2.getAdminArea());
                    userJSONObject.put("country",ad2.getCountryName());
                }
                catch (JSONException e){

                }
                userJSONArray.put(userJSONObject);
                String data=userJSONObject.toString();

                String loc=String.valueOf(geoCoordinates[0])+" * "+String.valueOf(geoCoordinates[1]);
                intent.putExtra("locationCoordinates",geoCoordinates);

                File locationFile=new File(getApplicationContext().getFilesDir(),"localLocationFile.txt");
                try {
                    FileOutputStream fos = new FileOutputStream(locationFile);
                    fos.write(data.getBytes());
                    fos.close();
                }
                catch (IOException e){

                }
                finish();
            }
        });

    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        final TextView textView=(TextView)findViewById(R.id.addressTextView);
        textView.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        mMap.setPadding(0, textView.getHeight(), 0, 0);
                    }
                }
        );

        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                finalLocation=latLng;
                MarkerOptions markerOptions=new MarkerOptions();
                markerOptions.position(latLng);
                mMap.clear();
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,15));
                mMap.addMarker(markerOptions);
            }
        });

        mFusedLocationClient= LocationServices.getFusedLocationProviderClient(this);
        mLocationRequest=new LocationRequest();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);


        mLocationCallback=new LocationCallback(){
            @Override
            public void onLocationResult(LocationResult locationResult)
            {
                if(locationResult==null){
                    return;
                }
                for(Location location : locationResult.getLocations())
                {
                    a=location.getLatitude();
                    b=location.getLongitude();
                    LatLng ll=new LatLng(a,b);
                    finalLocation=ll;
                    addPointToViewPort(ll);

                    markerLocation=mMap.addMarker(new MarkerOptions().position(ll).draggable(true));
                    mMap.moveCamera(CameraUpdateFactory.newLatLng(ll));
                    mMap.animateCamera(CameraUpdateFactory.zoomTo(17));
                    try{
                    mMap.setMyLocationEnabled(true);
                    }
                    catch(SecurityException e){

                    }

                    Geocoder geocoder=new Geocoder(LocationPickerActivity.this, Locale.getDefault());
                    List<Address> nearByList=null;
                    HashSet<String> ls=new HashSet<String>();
                    try {
                        nearByList = geocoder.getFromLocation(a, b, 1);
                    }
                    catch (IOException e){

                    }
                    Address ad=nearByList.get(0);
                    ls.add(ad.getPostalCode());
                }
            }
        };

        try {
            mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, null);
        }
        catch (SecurityException e){

        }

    }
}

答案 1 :(得分:0)

您是否正在使用特殊的库来显示osm映射?或尝试在网络视图上加载地图?

如果您不使用任何特殊的库,则可以使用OSMSHARP,并使用此代码可以将OSM映射添加到Xamarin.Android或Xamarin.ios项目:

Native.Initialize();

    var _mapView = new MapView(View.Frame);
    _mapView.MapCenter = new GeoCoordinate(52.207767, 8.803513);
    _mapView.MapZoom = 12;
    _mapView.Map.AddLayerTile("http://a.tile.openstreetmap.de/tiles/osmde/{0}/{1}/{2}.png");

    View.AddSubview(_mapView);

此代码会将mapView添加到您的根视图。

如果您还有其他问题,可以与软件包所有者联系。

另一种解决方案是使用Web视图显示osm映射。首先,您应该在活动中添加一个Web视图,然后应该在解决方案中添加Javascript界面​​类,使用该类可以在设备上保存互动。

首先,我们定义要用作或javascript接口的类:

 class MyJSInterface : Java.Lang.Object, Java.Lang.IRunnable
 {
    Context context;

    public MyJSInterface (Context context)
    {
        this.context = context;
    }

    public void AddNewPlace()
    {
        Toast.MakeText(context, "Hello from C#", ToastLength.Short).Show();
    }
}

下一步是在活动中定义Web视图,并将此类绑定为Web视图的接口

WebView webView = new WebView(this);
SetContentView(webView);

webView.Settings.JavaScriptEnabled = true;
webView.AddJavascriptInterface(new MyJSInterface(this), "deviceInterface");
webView.LoadData("PATH TO OSM PAGE THAT HOSTED IN SERVER", "text/html", null);

这是一个简单的html页面示例,我们将其加载到webView中以及如何从页面调用c#方法:

 <html>
   <body>
     <p>calling C# methods from JavaScript</p>
     <button type=""button"" onClick=""deviceInterface.AddNewPlace()"">Add Custom Marker or anything else</button>
   </body>
 </html>

现在我们可以从javascript调用此接口类方法: