简体   繁体   English

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

[英]Set marker with click on map OpenStreetMap In Android

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

The XML layout for maps activity also have a search edit text to search places using google maps. 地图活动的XML布局还具有搜索编辑文本,以使用Google地图搜索地点。 The XML layout for maps activity should contain 地图活动的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>

And in LocationPicker.java class you have to declare a variable of Marker&GoogleMap type. 在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){

        }

    }
}

Are you using a special library for showing osm map? 您是否正在使用特殊的库来显示osm映射? or trying to load map on a web view? 或尝试在网络视图上加载地图?

If you don't use any special library you can use OSMSHARP and using this codes you can add OSM map to your Xamarin.Android or Xamarin.ios projects: 如果您不使用任何特殊的库,则可以使用OSMSHARP并使用以下代码可以将OSM映射添加到Xamarin.Android或Xamarin.ios项目:

Native.Initialize(); 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);

this code will add mapView to your root view. 此代码会将mapView添加到您的根视图。

if you have more question you can contact with package owner. 如果您还有其他问题,可以与包裹所有者联系。

another solution is using web view for showing osm map. 另一个解决方案是使用Web视图显示osm映射。 first you should add a web view to your activity, then you should add Javascript interface classes to your solution, using this class you can save interactions on your device. 首先,您应该在活动中添加一个Web视图,然后应该在解决方案中添加Javascript接口类,使用该类可以将交互保存在设备上。

first we define a class that we want to use as or javascript interface: 首先,我们定义一个我们要用作或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();
    }
}

the next step is to define a web view in activity and bind this class as interface for web view 下一步是在活动中定义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);

this is a simple example of html page that we will load into webView and how we call c# methods from page: 这是一个简单的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>

now we can call this interface class methods from javascript: 现在我们可以从javascript调用此接口类方法:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM