Android
API di Google Maps v2 per Android
Ricerca…
Parametri
Parametro | Dettagli |
---|---|
Google Map | GoogleMap è un oggetto che viene ricevuto su un evento onMapReady() |
MarkerOptions | MarkerOptions è la classe builder di un Marker e viene utilizzata per aggiungere un marker a una mappa. |
Osservazioni
Requisiti
- L'SDK di Google Play Services è installato.
- Un account Google Console.
- Una chiave API di Google Maps ottenuta in Google Console.
Attività predefinita di Google Maps
Questo codice attività fornirà funzionalità di base per includere una mappa di Google utilizzando un SupportMapFragment.
L'API di Google Maps V2 include un modo completamente nuovo di caricare mappe.
Le attività ora devono implementare l'interfaccia OnMapReadyCallBack , che viene fornita con un metodo overMate su onMapReady () che viene eseguito ogni volta che viene eseguito SupportMapFragment . getMapAsync (OnMapReadyCallback) ; e la chiamata è stata completata con successo.
Mappe usare marcatori , poligoni e polilinee per visualizzare le informazioni interattivo per l'utente.
MapsActivity.java:
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney, Australia, and move the camera.
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
}
Si noti che il codice sopra gonfia un layout, che ha un SupportMapFragment nidificato all'interno del layout del contenitore, definito con un ID di R.id.map
. Il file di layout è mostrato di seguito:
activity_maps.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
tools:context="com.example.app.MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
</LinearLayout>
Stili di Google Maps personalizzati
Stile della mappa
Google Maps include una serie di stili diversi da applicare, utilizzando questo codice:
// Sets the map type to be "hybrid"
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
I diversi stili di mappa sono:
Normale
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
Tipica mappa stradale. Vengono mostrate strade, alcune caratteristiche create dall'uomo e importanti caratteristiche naturali come i fiumi. Sono inoltre visibili le etichette stradali e delle funzionalità.
Ibrido
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
Dati di fotografie satellitari con mappe stradali aggiunte. Sono inoltre visibili le etichette stradali e delle funzionalità.
Satellitare
map.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
Dati di fotografia satellitare Le etichette stradali e le caratteristiche non sono visibili.
Terreno
map.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
Dati topografici La mappa include i colori, le linee di contorno e le etichette e l'ombreggiatura prospettica. Sono anche visibili alcune strade ed etichette.
Nessuna
map.setMapType(GoogleMap.MAP_TYPE_NONE);
Nessuna tessera. La mappa verrà visualizzata come una griglia vuota senza tessere caricate.
ALTRE OPZIONI DI STILE
Mappe dell'interno
A livelli di zoom elevati, la mappa mostrerà le planimetrie per gli spazi interni. Queste sono chiamate mappe interne e sono visualizzate solo per i tipi di mappe "normali" e "satellite".
per abilitare o disabilitare le mappe interne, ecco come è fatto:
GoogleMap.setIndoorEnabled(true).
GoogleMap.setIndoorEnabled(false).
Possiamo aggiungere stili personalizzati alle mappe.
Nel metodo onMapReady aggiungi il seguente snippet di codice
mMap = googleMap;
try {
// Customise the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = mMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
MapsActivity.this, R.raw.style_json));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style.", e);
}
sotto la cartella res creare un nome di cartella raw e aggiungere il file json di stile. Esempio di file style.json
[
{
"featureType": "all",
"elementType": "geometry",
"stylers": [
{
"color": "#242f3e"
}
]
},
{
"featureType": "all",
"elementType": "labels.text.stroke",
"stylers": [
{
"lightness": -80
}
]
},
{
"featureType": "administrative",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#746855"
}
]
},
{
"featureType": "administrative.locality",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#d59563"
}
]
},
{
"featureType": "poi",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#d59563"
}
]
},
{
"featureType": "poi.park",
"elementType": "geometry",
"stylers": [
{
"color": "#263c3f"
}
]
},
{
"featureType": "poi.park",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#6b9a76"
}
]
},
{
"featureType": "road",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#2b3544"
}
]
},
{
"featureType": "road",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#9ca5b3"
}
]
},
{
"featureType": "road.arterial",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#38414e"
}
]
},
{
"featureType": "road.arterial",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#212a37"
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#746855"
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#1f2835"
}
]
},
{
"featureType": "road.highway",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#f3d19c"
}
]
},
{
"featureType": "road.local",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#38414e"
}
]
},
{
"featureType": "road.local",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#212a37"
}
]
},
{
"featureType": "transit",
"elementType": "geometry",
"stylers": [
{
"color": "#2f3948"
}
]
},
{
"featureType": "transit.station",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#d59563"
}
]
},
{
"featureType": "water",
"elementType": "geometry",
"stylers": [
{
"color": "#17263c"
}
]
},
{
"featureType": "water",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#515c6d"
}
]
},
{
"featureType": "water",
"elementType": "labels.text.stroke",
"stylers": [
{
"lightness": -20
}
]
}
]
Per generare stili file json, fare clic su questo collegamento
Aggiungere marcatori a una mappa
Per aggiungere marcatori a una mappa di Google, ad esempio da un ArrayList
di MyLocation
Objects, possiamo farlo in questo modo.
La classe titolare di MyLocation
:
public class MyLocation {
LatLng latLng;
String title;
String snippet;
}
Ecco un metodo che richiede un elenco di oggetti MyLocation
e inserisce un indicatore per ognuno:
private void LocationsLoaded(List<MyLocation> locations){
for (MyLocation myLoc : locations){
mMap.addMarker(new MarkerOptions()
.position(myLoc.latLng)
.title(myLoc.title)
.snippet(myLoc.snippet)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
}
}
Nota: ai fini di questo esempio, mMap
è una variabile membro della classe dell'attività, in cui l'abbiamo assegnata al riferimento mappa ricevuto nella sovrascrittura onMapReady()
.
MapView: incorporare un GoogleMap in un layout esistente
È possibile trattare un GoogleMap come una vista Android se utilizziamo la classe MapView fornita. Il suo utilizzo è molto simile a MapFragment.
Nel tuo layout usa MapView come segue:
<com.google.android.gms.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
<!--
map:mapType="0" Specifies a change to the initial map type
map:zOrderOnTop="true" Control whether the map view's surface is placed on top of its window
map:useVieLifecycle="true" When using a MapFragment, this flag specifies whether the lifecycle of the map should be tied to the fragment's view or the fragment itself
map:uiCompass="true" Enables or disables the compass
map:uiRotateGestures="true" Sets the preference for whether rotate gestures should be enabled or disabled
map:uiScrollGestures="true" Sets the preference for whether scroll gestures should be enabled or disabled
map:uiTiltGestures="true" Sets the preference for whether tilt gestures should be enabled or disabled
map:uiZoomGestures="true" Sets the preference for whether zoom gestures should be enabled or disabled
map:uiZoomControls="true" Enables or disables the zoom controls
map:liteMode="true" Specifies whether the map should be created in lite mode
map:uiMapToolbar="true" Specifies whether the mapToolbar should be enabled
map:ambientEnabled="true" Specifies whether ambient-mode styling should be enabled
map:cameraMinZoomPreference="0.0" Specifies a preferred lower bound for camera zoom
map:cameraMaxZoomPreference="1.0" Specifies a preferred upper bound for camera zoom -->
/>
La tua attività deve implementare l'interfaccia OnMapReadyCallback per funzionare:
/**
* This shows how to create a simple activity with a raw MapView and add a marker to it. This
* requires forwarding all the important lifecycle methods onto MapView.
*/
public class RawMapViewDemoActivity extends AppCompatActivity implements OnMapReadyCallback {
private MapView mMapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.raw_mapview_demo);
mMapView = (MapView) findViewById(R.id.map);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(this);
}
@Override
protected void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
public void onMapReady(GoogleMap map) {
map.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}
}
Mostra posizione corrente in una mappa di Google
Ecco una classe di attività completa che colloca un indicatore nella posizione corrente e sposta la telecamera nella posizione corrente.
Ci sono alcune cose che succedono in sequenza qui:
- Verifica l'autorizzazione di posizione
- Una volta concesso il permesso di posizione, chiama
setMyLocationEnabled()
, crea GoogleApiClient e collegalo - Una volta connesso GoogleApiClient, richiedi aggiornamenti sulla posizione
public class MapLocationActivity extends AppCompatActivity
implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
GoogleMap mGoogleMap;
SupportMapFragment mapFrag;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setTitle("Map Location Activity");
mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFrag.getMapAsync(this);
}
@Override
public void onPause() {
super.onPause();
//stop location updates when Activity is no longer active
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
@Override
public void onMapReady(GoogleMap googleMap)
{
mGoogleMap=googleMap;
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
}
else {
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onConnectionSuspended(int i) {}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {}
@Override
public void onLocationChanged(Location location)
{
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);
//move map camera
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(11));
//stop location updates
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(this)
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept to use location functionality")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MapLocationActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
})
.create()
.show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mGoogleMap.setMyLocationEnabled(true);
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
tools:context="com.example.app.MapLocationActivity"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
</LinearLayout>
Risultato:
Mostra spiegazione se necessario su Marshmallow e Nougat utilizzando un AlertDialog (questo caso si verifica quando l'utente ha precedentemente negato una richiesta di autorizzazione o ha concesso l'autorizzazione e successivamente lo ha revocato nelle impostazioni):
Richiedi all'utente l'autorizzazione di posizione su Marshmallow e Nougat chiamando ActivityCompat.requestPermissions()
:
Sposta la videocamera nella posizione corrente e posiziona il marcatore quando viene concessa l'autorizzazione di posizione:
Ottenimento dell'impronta SH1 del file del keystore del certificato
Per ottenere una chiave API di Google Maps per il tuo certificato, devi fornire alla console API l'impronta SH1 del tuo keystore di debug / release.
È possibile ottenere il keystore utilizzando il programma keytool di JDK come descritto qui nella documentazione.
Un altro approccio è ottenere l'impronta digitale a livello di codice eseguendo questo frammento con l'app firmata con il certificato di debug / release e stampando l'hash nel log.
PackageInfo info;
try {
info = getPackageManager().getPackageInfo("com.package.name", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md;
md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String hash= new String(Base64.encode(md.digest(), 0));
Log.e("hash", hash);
}
} catch (NameNotFoundException e1) {
Log.e("name not found", e1.toString());
} catch (NoSuchAlgorithmException e) {
Log.e("no such an algorithm", e.toString());
} catch (Exception e) {
Log.e("exception", e.toString());
}
Non lanciare Google Maps quando si fa clic sulla mappa (modalità lite)
Quando una mappa di Google viene visualizzata in modalità lite, facendo clic su una mappa si aprirà l'applicazione Google Maps. Per disabilitare questa funzionalità è necessario chiamare setClickable(false)
su MapView
, ad esempio :
final MapView mapView = (MapView)view.findViewById(R.id.map);
mapView.setClickable(false);
UISettings
Utilizzando UISettings
, è possibile modificare l'aspetto di Google Map.
Ecco un esempio di alcune impostazioni comuni:
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mGoogleMap.getUiSettings().setMapToolbarEnabled(true);
mGoogleMap.getUiSettings().setZoomControlsEnabled(true);
mGoogleMap.getUiSettings().setCompassEnabled(true);
Risultato:
Ottieni l'impronta digitale SHA1 di debug
- Apri Android Studio
- Apri il tuo progetto
- Clicca su Gradle (dal pannello laterale destro, vedrai Gradle Bar )
- Fai clic su Aggiorna (fai clic su Aggiorna dalla barra del gradino , vedrai gli script del Gradle della lista del tuo progetto)
- Clicca sul tuo progetto (il tuo elenco dei nomi dei progetti (root))
- Clicca su Attività
- Clicca su Android
- Doppio clic su signingReport (otterrai SHA1 e MD5 nella barra di esecuzione )
Listener del clic di InfoWindow
Ecco un esempio di come definire un'azione diversa per ogni evento clickWindow di ogni Marker.
Utilizzare una HashMap in cui l'ID del marker è la chiave e il valore è l'azione corrispondente che deve essere eseguita quando si fa clic su InfoWindow.
Quindi, utilizzare OnInfoWindowClickListener
per gestire l'evento di un utente facendo clic su InfoWindow e utilizzare HashMap per determinare l'azione da intraprendere.
In questo semplice esempio verrà aperta un'attività diversa in base alla quale è stato fatto clic su InfoWindow di Marker.
Dichiarare HashMap come variabile di istanza dell'attività o Frammento:
//Declare HashMap to store mapping of marker to Activity
HashMap<String, String> markerMap = new HashMap<String, String>();
Quindi, ogni volta che aggiungi un marcatore, crea una voce in HashMap con l'ID marcatore e l'azione che deve compiere quando si fa clic su InfoWindow.
Ad esempio, aggiungendo due marcatori e definendo un'azione da intraprendere per ciascuno:
Marker markerOne = googleMap.addMarker(new MarkerOptions().position(latLng1)
.title("Marker One")
.snippet("This is Marker One");
String idOne = markerOne.getId();
markerMap.put(idOne, "action_one");
Marker markerTwo = googleMap.addMarker(new MarkerOptions().position(latLng2)
.title("Marker Two")
.snippet("This is Marker Two");
String idTwo = markerTwo.getId();
markerMap.put(idTwo, "action_two");
Nel listener dei clic di InfoWindow, ottieni l'azione da HashMap e apri l'attività corrispondente in base all'azione del Marcatore:
mGoogleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
String actionId = markerMap.get(marker.getId());
if (actionId.equals("action_one")) {
Intent i = new Intent(MainActivity.this, ActivityOne.class);
startActivity(i);
} else if (actionId.equals("action_two")) {
Intent i = new Intent(MainActivity.this, ActivityTwo.class);
startActivity(i);
}
}
});
Nota Se il codice si trova in un frammento, sostituire MainActivity.this con getActivity ().
Modifica offset
Cambiando MapPoint valori xey di cui hai bisogno è possibile cambiare possition offset del google map, per impostazione predefinita, sarà al centro della mappa. Chiama sotto il metodo dove vuoi cambiarlo! Meglio usarlo all'interno di onLocationChanged
come changeOffsetCenter(location.getLatitude(),location.getLongitude());
public void changeOffsetCenter(double latitude,double longitude) {
Point mappoint = mGoogleMap.getProjection().toScreenLocation(new LatLng(latitude, longitude));
mappoint.set(mappoint.x, mappoint.y-100); // change these values as you need , just hard coded a value if you want you can give it based on a ratio like using DisplayMetrics as well
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLng(mGoogleMap.getProjection().fromScreenLocation(mappoint)));
}