如何在Android或Xamarin.Android中单击地图并在开放的街道地图上添加书签
答案 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调用此接口类方法: