Ionic capacitor google maps setMapType not working - google-maps

I am using GoogleMap from #capacitor/google-maps plugin. I am trying to change the map type from Normal to Satellite. But this is not working.
await this.map.setMapType(MapType.Satellite);

I have recently found solution for this issue. Integrate 2 separate functions for browser and native devices.
For browser:
async createMapForWeb(map: ElementRef) {
this.map = await GoogleMap.create({
id: "capacitor-google-maps",
element: map.nativeElement,
apiKey: environment.browserKey,
config: {
zoom: 18,
mapTypeControl: false,
center: {
lat: this.location.lat,
lng: this.location.lng,
},
mapTypeId: "satellite",
disableDefaultUI: true,
},
forceCreate: true,
});
}
For native devices:
async createMapForDevice(map: ElementRef) {
this.map = await GoogleMap.create({
id: "capacitor-google-maps",
element: map.nativeElement,
apiKey: environment.browserKey,
config: {
zoom: 18,
mapTypeControl: false,
center: {
lat: this.location.lat,
lng: this.location.lng,
},
disableDefaultUI: false,
},
forceCreate: true,
});
await this.map.setMapType(MapType.Satellite);}

Extending Ariyan Ashfaque's answer below:
You can make use of Capacitor.isNativePlatform() to identify browser / native device.
import { Capacitor } from '#capacitor/core';
const createMap = async () => {
if (!mapRef.current) return;
if (Capacitor.isNativePlatform()) {
console.warn('Native Platform Map');
newMap = await GoogleMap.create({
id: 'google-map',
element: mapRef.current,
apiKey: CONFIG.GOOGLE_MAPS_API_KEY,
config: mapConfig,
forceCreate: true,
});
await newMap.setMapType(MapType.Satellite);
await newMap.enableCurrentLocation(true);
} else {
console.warn('Browser Map');
newMap = await GoogleMap.create({
id: 'google-map',
element: mapRef.current,
apiKey: CONFIG.GOOGLE_MAPS_API_KEY,
config: mapConfig,
forceCreate: true,
});
}
await newMap.addMarker({
coordinate: {
lat: props?.geoLocation?.latitude,
lng: props?.geoLocation?.longitude,
},
title: 'Marker Title',
});
await Geolocation.getCurrentPosition();
};

Related

Implementing google markerclusterer plus into stencil webcomponents

I read a lot about how to implementing external files into stencil but nothing worked yet like I want it. The speciality is that stencil runs in a Liferay theme. But I think that shouldn't matter.
I installed the MarkerClustererPlus from google via npm and in the stencil config i copy the min file into an "asset" folder like this:
import { Config } from '#stencil/core';
import { sass } from '#stencil/sass';
import nodePolyfills from 'rollup-plugin-node-polyfills';
export const config: Config = {
namespace: 'gwkp-components',
srcDir: 'src/js/components',
plugins: [
sass({
injectGlobalPaths: [
'build/css/clay/_mixins.scss',
'build/css/fonts/font-awesome/scss/_mixins.scss',
'build/css/fonts/font-awesome/scss/_variables.scss',
'build/css/fonts/font-awesome/scss/_core.scss',
'src/js/components/utils/_stencilvars.scss',
'build/css/fonts/font-awesome/scss/regular.scss',
'build/css/fonts/font-awesome/scss/light.scss',
'build/css/fonts/font-awesome/scss/solid.scss',
'build/css/clay/bootstrap/_functions.scss',
'build/css/clay/bootstrap/_mixins.scss',
'build/css/clay/bootstrap/_variables.scss',
'src/css/gw/_colors.scss',
'src/css/gw/_variables.scss',
'src/css/gw/bem/_includes.scss'
]
})
],
outputTargets: [
{
type: 'www',
buildDir: '.',
dir: 'build/js/components',
serviceWorker: null, // disable service workers
copy: [
{ src: '../../../build/css/fonts/font-awesome/webfonts', dest: 'webfonts' },
{ src: '../../../node_modules/#google/markerclustererplus/dist/markerclustererplus.min.js', dest: 'assets/js/markerclustererplus.min.js' }
]
}
],
rollupPlugins: {
after: [
nodePolyfills()
]
}
};
Now the question arises how to get access to the min.js file? Do I need an import statement and declaring a variable or create a script tag? I tried both in some way but nothing worked so far. I need it only in one component.
At the end I wanna use the following code in the component:
var markerCluster = new MarkerClusterer(this.map, this.markerMap,
{imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'});
No need to copy node_modules/#google/markerclustererplus/dist/markerclustererplus.min.js to assets/js/markerclustererplus.min.js.
In your component's tsx file just import MarkerCluster
import MarkerClusterer from "#google/markerclustererplus";
You'll need to have the google maps javascript library already loaded. As far as I'm aware you'll have to load it via a script tag but this can be done dynamically.
I'm using // #ts-ignore in my examples but you can install the Google Maps types if you prefer.
The final component should look something like the following:
import { h, Component, Host, Element, Listen } from "#stencil/core";
import MarkerClusterer from "#google/markerclustererplus";
#Component({
tag: "my-component",
styles: `
:host {
position: absolute;
width: 100%;
height: 100%;
}
.map {
height: 100%;
}
`,
shadow: true,
})
export class MyComponent {
#Element() el: HTMLElement;
private googleMapsApiKey = "YOUR_API_KEY_HERE";
private locations = [
{ lat: -31.56391, lng: 147.154312 },
{ lat: -33.718234, lng: 150.363181 },
{ lat: -33.727111, lng: 150.371124 },
{ lat: -33.848588, lng: 151.209834 },
{ lat: -33.851702, lng: 151.216968 },
{ lat: -34.671264, lng: 150.863657 },
{ lat: -35.304724, lng: 148.662905 },
{ lat: -36.817685, lng: 175.699196 },
{ lat: -36.828611, lng: 175.790222 },
{ lat: -37.75, lng: 145.116667 },
{ lat: -37.759859, lng: 145.128708 },
{ lat: -37.765015, lng: 145.133858 },
{ lat: -37.770104, lng: 145.143299 },
{ lat: -37.7737, lng: 145.145187 },
{ lat: -37.774785, lng: 145.137978 },
{ lat: -37.819616, lng: 144.968119 },
{ lat: -38.330766, lng: 144.695692 },
{ lat: -39.927193, lng: 175.053218 },
{ lat: -41.330162, lng: 174.865694 },
{ lat: -42.734358, lng: 147.439506 },
{ lat: -42.734358, lng: 147.501315 },
{ lat: -42.735258, lng: 147.438 },
{ lat: -43.999792, lng: 170.463352 },
];
private _mapEl: HTMLElement;
componentDidLoad() {
if (document.getElementById("maps-script")) {
this.initMap();
return;
}
// Create the script tag, set the appropriate attributes
var script = document.createElement("script");
script.id = "maps-script";
script.src = `https://maps.googleapis.com/maps/api/js?key=${this.googleMapsApiKey}&callback=initMap`;
script.defer = true;
// Attach your callback function to the `window` object
// #ts-ignore
window.initMap = () => this.initMap();
// Append the 'script' element to 'head'
document.head.appendChild(script);
}
initMap() {
// #ts-ignore
const map = new google.maps.Map(this._mapEl, {
zoom: 3,
center: { lat: -28.024, lng: 140.887 },
});
// Create an array of alphabetical characters used to label the markers.
const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Add some markers to the map.
// Note: The code uses the JavaScript Array.prototype.map() method to
// create an array of markers based on a given "locations" array.
// The map() method here has nothing to do with the Google Maps API.
const markers = this.locations.map((location, i) => {
// #ts-ignore
return new google.maps.Marker({
position: location,
label: labels[i % labels.length],
});
});
// Add a marker clusterer to manage the markers.
const markerCluster = new MarkerClusterer(map, markers, {
imagePath:
"https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m",
});
}
render() {
return (
<Host>
<div class="map" ref={(el) => (this._mapEl = el)}></div>
</Host>
);
}
}
Here is a Working example on webcomponents.dev

add multiple gmap marker

i have a vue2-google-map apps that display map.
before this i using this code
<GmapMarker
ref="myMarker"
:position="google && new google.maps.LatLng(1.38, 103.8)"
/>
<GmapMarker
ref="myMarker"
:position="google && new google.maps.LatLng(3.1488976, 101.6126774)"
/>
to display multiple marker, but if the latlng data is too many, it will be many need to be create.
my idea is to take data from
const latlng = [
{
lat: value,
lng: value,
},
{
lat: value,
lng: value,
},
and apply {{latlng}} into <GmapMarker :position="google && new google.maps.LatLn({{latlng.lng}},{{latlng.lat}})">
but i have problem to apply that {{latlng}} into the marker.
can someone explain how to apply them?
For generating multiple markers your need to push latitude and longitude in the marker collection and then iterate the marker.i have updated code as per the requirement.
<template>
<div>
<GmapMap
ref="gmap"
:center="getCenter()"
:zoom="11"
style="height: 500px;margin: 0px -8px;"
class="no-padding"
:options="getOptions()"
>
<GmapMarker
:key="index"
v-for="(m, index) in getMarkers()"
:position="m.position"
:clickable="true"
:draggable="false"
:title="m.title"
:icon="m.icon"
#click="clicked()"
/>
</GmapMap>
</div>
</template>
<script>
import MarkerClusterer from "marker-clusterer-plus";
export default {
name: "SiteMap",
props: [],
methods: {
getOptions() {
return {
zoomControl: true,
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
rotateControl: false,
fullscreenControl: false,
disableDefaultUi: false
};
},
clicked() {
// after click
},
getCenter() {
return {
lat: 37.12523,
lng: -122.1252
};
},
getMarkers() {
// generating markers for site map
var markers = [];
// remove this after lat long received from api.
const tempLatLong = [
{ lat: 37.9068361, lng: -122.116971 },
{ lat: 37.9168362, lng: -122.076972 },
{ lat: 37.9268363, lng: -122.136973 },
{ lat: 37.9368364, lng: -122.146974 },
{ lat: 37.9468365, lng: -122.106975 },
{ lat: 37.9568366, lng: -122.166976 },
{ lat: 37.9668367, lng: -122.176977 },
{ lat: 37.9768368, lng: -122.016978 },
{ lat: 37.9868369, lng: -122.196979 }
];
for(let i=0;i<tempLatLong.length;i++){
markers.push({
position: tempLatLong[i],
title: 'test title',
icon: this.getSiteIcon(1) // if you want to show different as per the condition.
});
}
return markers;
},
getSiteIcon(status) {
try {
switch (status) {
case 1:
return require("#/assets/images/icons/map-marker-online.svg");
break;
case 2:
return require("#/assets/images/icons/map-marker-critical.svg");
break;
case 3:
return require("#/assets/images/icons/map-marker-offline.svg");
break;
case 4:
return require("#/assets/images/icons/map-marker-lifesafety.svg");
break;
default:
return require("#/assets/images/icons/map-marker-online.svg");
}
} catch (e) {
return null;
}
},
},
components: {},
created() {},
mounted() {
}
};
</script>
<style scoped></style>

drawing a path between two marker on ionic 3

Hey im new on ionic i wanted to draw a path between two markers (two points) using the google maps api but im blocked with that piece of code
Well by seeing a lot of tutorial i can't find any documentation about the route drawing by ionic their github repository never mentionned the route drawing i think it's not supported .
loadMap() {
let mapOptions: GoogleMapOptions = {
camera: {
target: {
lat: this.agence.latitude,
//43.0741904,
lng: this.agence.longitude,
//-89.3809802
},
zoom: 14,
tilt: 30
}
};
this.map = GoogleMaps.create('map', mapOptions);
let marker: Marker = this.map.addMarkerSync({
title: 'Radeema'+this.agence.nom,
icon: 'red',
animation: 'DROP',
position: {
lat: this.agence.latitude,
lng: this.agence.longitude
}
});
let positionMarker: Marker = this.map.addMarkerSync({
title: 'votre position',
icon: 'blue',
animation: 'DROP',
position: {
lat: this.latitude,
lng: this.longitude,
}
});
this.map.addMarker({
title: 'votre position',
icon: 'green',
animation: 'DROP',
position: {
lat: this.latitude,
lng: this.longitude,
}
})
let directionsService = new google.maps.DirectionsService;
let directionsDisplay = new google.maps.DirectionsRenderer;
directionsService.route({
origin:{"lat": this.latitude, "lng": this.longitude} ,
destination: {"lat": this.agence.latitude, "lng": this.agence.longitude},
travelMode: google.maps.TravelMode['DRIVING']
}, (res, status) => {
if(status == google.maps.DirectionsStatus.OK){
directionsDisplay.setDirections(res);
} else {
console.warn(status);
}
});
this.map.addPolyline({
points: [
{"lat": this.latitude, "lng": this.longitude},
{"lat": this.agence.latitude, "lng": this.agence.longitude},
],
'color' : '#fff51e',
'width': 10,
'geodesic': true
}); }
what should i do in this case i can't understand the source of the error
From documentation, converted from js to ts:
private directionService = new google.maps.DirectionsService;
private directionsDisplay = new google.maps.DirectionsRenderer;
initMap() {
let map = new google.maps.Map(document.getElementById('map'), {
zoom: 7,
center: { lat: 41.85, lng: -87.65 }
});
this.directionsDisplay.setMap(map);
}
onChangeHandler() { // use this function in your dom or in your code when you want to dislpay the route
calculateAndDisplayRoute();
};
calculateAndDisplayRoute() {
this.directionsService.route({
origin: userLocation,
destination: agenceLocation,
travelMode: 'DRIVING'
}, (response, status) => {
if (status === 'OK') {
this.directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
However I recommand this plugin which let the user chose his favorite navigation application.

How to retrieve data from a store in Sencha Touch

Now I have my store: stuStore set up which contains some mock-up data.
I have another page which is a Google Map.
Student data structure: {name, geolocation,value, etc....}
I would like to display each of students info based on their locations which is inside of stuStore onto the google Map.
Here is the code:
Ext.define('myapp.view.Main', {
extend: 'Ext.tab.Panel',
xtype: 'main',
fullscreen: true,
requires: [
'Ext.TitleBar',
'Ext.Video',
'Ext.Map',
'Ext.Panel',
'Ext.tab.*',
'Ext.*'
],
config: {
tabBarPosition: 'bottom',
items: [
{
title: 'myapp',
iconCls:'maps',
xtype: 'map',
useCurrentLocation: true,
store: 'myapp.store.stuStore'
}
How can I do it?
Update 1
var mapdemo = Ext.create('Ext.Map', {
mapOptions: {
center: new google.maps.LatLng(-37.73228, 144.86900), //nearby San Fran
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP,
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.DEFAULT
}
},
title: 'MyApp',
iconCls: 'maps',
fullscreen: true,
xtype: 'map',
id: 'mainMap',
useCurrentLocation: false,
listeners: {
maprender: function (comp, googleMap) {
var store, latlng, marker;
store = Ext.getStore('myapp.store.stuStore');
store.each(function (record, index, length) {
latlng = new google.maps.LatLng(record.get('Lat'), record.get('Lng'));
marker = new google.maps.Marker({
position: latlng,
map: this
});
});
}
}
}),
infowindow = new google.maps.InfoWindow({
content: 'Sencha HQ'
});
Ext.define('myapp.view.Main', {
extend: 'Ext.tab.Panel',
xtype: 'main',
fullscreen: true,
config: {
tabBarPosition: 'bottom',
items: [mapdemo],
}
});
This is my updated code in view\Main.js
But I don't get any markers and it keeps throwing an error:
Uncaught TypeError: Cannot call method 'each' of undefined
Incidentally, the icon on the toolbar which is docked at bottom of the screen is gone as well.
What can I try next?
You can create markers based on store records by looping through them in the maprender event callback like this:
Ext.define('myapp.controller.MapController', {
extend: 'Ext.app.Controller',
config: {
refs: {
mapComponent: 'main map'
},
control: {
mapComponent: {
maprender: 'onMaprender',
}
}
},
onMaprender: function(mapComponent, googleMap) {
var store, latLng, marker;
// Get store
store = Ext.getStore('myapp.store.stuStore')
// On each store record
store.each(function(record, index, length) {
// Get position
latLng = new google.maps.LatLng(record.get('lat'), record.get('lng'));
// Create marker
marker = new google.maps.Marker({
position: latLng,
map: googleMap
});
});
}
});
Have a look at this Sencha Fiddle I put together.

Sencha Touch 2: Google Maps Directions Route won't show

I'm using a view to show a location on a map with a small form below it to grab the users address if they want directions. The map renders initially as I want. There is a controller to handle tapping the button and updating the display with the route. I can see that it is successfully retrieving the route information. It's just not updating the display to show it. What am I missing?
Here's the view:
var tcmlatlng = new google.maps.LatLng(38.898748, -77.037684);
Ext.define('VisitTCMIndy.view.Directions',{
extend: 'Ext.Panel',
requires: [
'Ext.form.Panel',
'Ext.Map'
],
config: {
layout: 'vbox',
items: [
{
xtype: 'map',
useCurrentLocation: false,
flex: 3,
mapOptions: {
center: tcmlatlng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
},
listeners: {
maprender: function(map,gmap,options){
var homemarker = new google.maps.Marker({
position: tcmlatlng,
map: gmap
});
}
}
},
{
xtype: 'formpanel',
id: 'directionsform',
flex: 1,
items:[
{
xtype: 'textfield',
name: 'address',
label: 'Address',
},
{
xtype: 'button',
ui:'action',
text: 'Get Directions'
}
]
}
]
}
});
Here's the controller
Ext.define('VisitTCMIndy.controller.Directions',{
extend: 'Ext.app.Controller',
config: {
control: {
dButton: {
tap: 'loaddirections'
}
},
refs: {
dButton: '#directionsform button[ui=action]',
tcmmap:'map',
addfield:'textfield[name=address]'
}
},
loaddirections: function(dbutton){
console.log('loaddirections');
var gmap = this.getTcmmap();
var directionsDisplay = new google.maps.DirectionsRenderer();
var directionsService = new google.maps.DirectionsService();
directionsDisplay.setMap(gmap.map);
var tcmadd = "1600 Pennsylvania Ave, Washington, DC";
var originadd = this.getAddfield().getValue();
var request = {
origin: originadd,
destination: tcmadd,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(result, status){
console.log(status);
if(status = google.maps.DirectionsStatus.OK){
console.log(result);
directionsDisplay.setDirections(result);
}
});
}
});
I was referencing the map incorrectly. I was trying to reference it directly instead of using the getter. So anywhere you see 'gmap.map' it should read 'gmap.getMap()'.