Enhancing Your Map with Google Maps 3.54's New Style Features

I am currently working on a project using Vue2 with version 3.54 of Google Maps, which is necessary for the advancedMarkers feature.

https://maps.googleapis.com/maps/api/js?key=${this.mapKey}&callback=isMapLoad&libraries=marker&v=3.54

I have gone through all the documentation on styling maps and have successfully styled maps in previous versions. However, I am facing difficulty in implementing it now.

I attempted to set a style during initialization:

this.map = new google.maps.Map(document.getElementById('map'), {
  mapId: 'GMAP_ID',
  language: this.$i18n.locale,
  center: this.defaultCoords,
  zoom: this.zoom,
  styles: [
  {
    featureType: 'water',
    elementType: 'all',
    stylers: [
     {
       color: '#f40000',
     },
     {
       visibility: 'on',
     },
    ],
  }
 ]
})

And also tried setting it after initialization:

const styledMapType = new google.maps.StyledMapType(
 [
  {
    featureType: 'water',
    elementType: 'all',
    stylers: [
     {
       color: '#f40000',
     },
     {
       visibility: 'on',
     },
    ],
  }
 ]
)
this.map.mapTypes.set('styled_map', styledMapType)
this.map.setMapTypeId('styled_map')

// Added libraries maps to script URL to enable StyledMapType

Despite not receiving any errors, no changes were reflected in both cases. What else can I try?


UPDATE

A functional example showcasing the issue can be found here: https://jsfiddle.net/981w4zxb/1/

If you remove the mapId as shown in the example, the style is applied, but the markers cease to function. On the other hand, adding the mapid displays advanced markers but does not apply the styles.

The goal is to incorporate both - utilizing advanced markers along with legacy styles without reliance on the cloud service.

Answer №1

Currently, there is no direct way to upload or import JSON from Google Map Console/Platform for custom styling of Google Maps.

However, you can achieve custom styles by incorporating code on your end. I have successfully implemented this approach in an Angular project.

Sample Code -

import { Loader } from '@googlemaps/js-api-loader';

ngOnInit(): void {
  const loader = new Loader({
    apiKey: API_KEY,
    version: 'weekly'
  });

  loader.importLibrary('maps').then(() => {
    void this.initMap();
  }).catch((error: Error) => {
    console.error(`Error loading Google Maps API: ${error.message}`);
  });
}

async initMap(): Promise <void> {
  const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;

  const mapOptions = {
    zoom: 7,
    center: {
      lat: 22.5744,
      lng: 88.3629
    },
  };

  const map = new Map(document.getElementById('map'), mapOptions);

  const styledMapType = new google.maps.StyledMapType(
    [
      {
        featureType: 'water',
        elementType: 'all',
        stylers: [
          {
            color: '#f40000',
          },
          {
            visibility: 'on',
          },
        ],
      }
    ]
  );
  this.map.mapTypes.set('styled_map', styledMapType);
  this.map.setMapTypeId('styled_map');
}

Resultant Output -

https://i.sstatic.net/G8tNHHQE.png

Google maps package version details -

"@angular/core": "^17.2.0",
"@angular/google-maps": "^17.2.0",
"@googlemaps/js-api-loader": "^1.16.6",
"@googlemaps/markerclusterer": "^2.5.3",

Answer №2

Not entirely certain how this will work in Vue, but your code appears to be accurate – regardless of whether or not you include &v=3.54.

The crucial point here is that if you initialize your map with a mapId, the styles attribute within the constructor will not take precedence over the map's visual representation.

Therefore, if there are no cloud styles associated with your mapId, it is recommended to exclude it from the constructor. Your styles should then be applied immediately, along with the potential impact of this.map.setMapTypeId(...).

UPDATE

You cannot simultaneously use mapIds and apply custom styles. Combining these elements will trigger a warning message:

The styles property of a Map cannot be configured when a mapId is specified. If a mapId is present, styling must be managed via the Google Cloud Console. For more information, refer to the documentation at https://developers.google.com/maps/documentation/javascript/styling#cloud_tooling

Considering that your style definitions are stored in a database, it may be necessary to create individual mapIds along with their corresponding cloud styles…

Alternatively, you could reconsider your reliance on Advanced Markers. Check out this guide for exploring alternative approaches. Disclaimer: I authored the guide.

Lastly, it might be beneficial to monitor the progress of the gcloud cli, which could potentially offer functionality to programmatically generate mapIds and styles in the future -- similar to what Google has done for API Keys.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using JavaScript and React to determine the height of a dynamically generated section containing multiple div blocks

Looking for a JS/React solution to dynamically count the height or number of lines in draggable div blocks with varying widths. The goal is to calculate the content height inside a dashed border, which should be equal to (viewport - draggable_blocks_height ...

Create a new promise within a factory function

I am facing an issue in my factory where I want to return a promise inside a function, but every time I try, my controller throws an error like: Provider 'personFactory' must return a value from $get factory method. This is how my factory looks ...

Discover the Primevue DataTable feature that enables dynamic column and column grouping functionality, with the added bonus of gridlines disappearing as you scroll down

I am currently utilizing the PrimeVue DataTable feature with dynamic column and column grouping. Initially, when the table loads, everything appears to be great - gridlines are visible, columns freeze, scrollable functionality is working as expected. htt ...

Exploring Vue and Vuetify: How to iterate over an array of strings and execute each function within an object?

In my current setup, I have an array that holds various validation rules: FieldValidationRules: ["isRequired", "isMinLength"] Within my input component, I have an object that includes multiple rule functions: rules: { isRequired: (value) => !!val ...

Form validation using jQuery and AJAX

I've implemented validation in my ResetPassword function and it seems to be working fine. However, I'm facing an issue where the ResetPassword function stops working once the validation is added. Can someone guide me on how to resolve this issue? ...

Scrolling through four limited list items automatically

Hey there! I am currently working on a design project. You can check it out here. I'm trying to replicate a section from another site, which you can see here. <div class="latest-winners-container"> <h3 class="header">Latest Winners< ...

What is the best way to invoke a custom hook that returns a value within the useEffect hook?

I have a unique situation where I am using a custom hook that returns an object based on the parameter it receives. I now need to modify this behavior by recreating the object with updated parameters within the useEffect function. The challenge is that I c ...

Problem arises when attempting to switch between JQuery UI tabs by clicking a button

I am currently utilizing Jquery UI tabs. Let me explain my issue to you, so here are the jquery codes for UI ajax Tabs that I am using. $(function () { $("#tabs").tabs({ beforeLoad: function (event, ui) { if (ui.tab.data("loaded")) { ...

vue Passing data to a Vue component and retrieving the selected value

Within my summary route, each nested route features a header containing a radio group. To display this header on all nested routes, I have utilized summary.vue located in the root of the pages folder and included <nuxt-child>. pages/summary.vue &l ...

Receiving and transmitting messages repeatedly in Discord.JS

Currently, I am developing a simple bot. Interestingly, the bot seems to be responding multiple times to a single command. Here is the code snippet: const Discord = require('discord.js'); var bot = new Discord.Client(); const PREFIX = "+"; var ...

Elements added through d3 and jquery are not showing up in the SVG

I am experiencing an issue with a line chart created using d3. I am appending text elements to each datapoint (svg circle element) using d3 and jquery, but the elements are not appearing on the chart. Interestingly, when I manually edit the HTML in Chrome ...

Creating a complete webpage using HTML

Is there a method to load an HTML file and execute the embedded javascript to create a complete HTML page programmatically similar to how browsers do? Edit 1 - I am working on an application where I need to extract data from an HTML page on a remote websi ...

Pass a notification to a separate function

Issue Looking for a way to send an 'event' to another function using jQuery. The goal is to prevent the removal of a table row before executing certain treatments, and then remove the row. I want to insert a modal window in between these actions ...

Configuring the text box to utilize jQuery's datepicker feature

Currently, I am facing an issue with setting up a datepicker in a dynamic control creation scenario. The control is being created on the fly, causing inconsistencies with the id, which in turn is preventing the datepicker from functioning properly. Here is ...

Modify AngularJS behavior to show or hide elements when the user hovers over them

In my template, I display a series of "icons". <div ng-repeat="data in items | orderBy:'-timestamp'"> <div class="icon"> <i>1</i> <span>2</span> </div> </div> To hide i and ...

The light slider feature is experiencing technical difficulties within the Bootstrap model

I am experiencing an issue with the Light Slider in a Bootstrap modal. Strangely, when I press F12 for inspect element, the Light Slider starts working. For more details and to see the link provided in the comment below, can anyone offer assistance, plea ...

Using an array key within a file name

Within an array, there are pairs of key-value combinations like the following: ranks: [ { r_mil_pvt_e2: 'Private E-2', r_mar_seaman_rcr: 'Seaman Recruit', [...] } The key essentially represents a filename loc ...

I'm interested in learning about the most efficient practices for handling JSON, performing math operations, and utilizing loops in JS/React. What techniques

Short version: I'm working with a large array of JSON objects (60K+ elements) in my application I need to perform various mathematical operations such as comparison and addition Currently, I am handling this through multiple for loops (simplified ...

Experiencing difficulty in removing a row from an HTML table using jQuery DataTables

I have an HTML table populated with data from the database. My goal is to be able to delete a row from the HTML table without affecting the actual data in the database. Each row in the table has a delete button in the action column, and when clicked, tha ...

When invoking the jQuery ".load('pageName')" method, HTML pages are not loaded from the application cache

I have been working on incorporating the html5 offline caching functionality into our html pages, and everything seems to be running smoothly with jQuery version 1.4. However, I encountered a problem when I upgraded to jQuery 1.8. Specifically, issues aro ...