Utilizing Typescript to create a specialized CustomOverlay class in the BingMaps Api

Currently in the process of upgrading a TypeScript application from using Bing Maps API version 7 to version 8. As part of this transition, I am aiming to convert the existing Overlay Component into a TypeScript class that implements the Microsoft.Maps.CustomOverlay class.

In my research, I came across a post on the MSDN forums discussing an issue with creating an overlay. You can check out the conversation here. Unfortunately, I've encountered a loading error during the migration process and I suspect it might be related to how the TypeScript compiled files are being loaded before the Bing Maps API library. I'm unsure of how to resolve this error.

Could it be that I overlooked something crucial?

Answer №1

Developing multiple TypeScript modules that extend the CustomOverlay class has been a smooth process for me. Below is one of the modules I have created.

Check out the module code:

/// <reference path="MicrosoftMaps/Microsoft.Maps.d.ts"/>

/**
* This interface defines the options for rendering a ground overlay on the map.
*/
interface IGroundOverlayOptions extends Microsoft.Maps.ICustomOverlayOptions {
    /** A background color to fill the area beneath the ground overlay. */
    backgroundColor?: string | Microsoft.Maps.Color;

    /** The bounding box to anchor the ground overlay to. */
    bounds: Microsoft.Maps.LocationRect;

    /** URL of the image to be used as a ground overlay. */
    imageUrl: string;

    /** Opacity of the ground overlay image. */
    opacity?: number;

    /** Rotation angle in degrees (counter-clockwise). 0 = north, 90 = west, 180 = south, 270 = east */
    rotation?: number;

    /** Boolean indicating the visibility of the ground overlay. */
    visible?: boolean;
}

/**
 * Custom overlay class that associates an image with a specified area on the map.
 */
class GroundOverlay extends Microsoft.Maps.CustomOverlay {

    /***********************************
    * Private Properties
    ***********************************/

    private _options: IGroundOverlayOptions = {
        beneathLabels: true,
        backgroundColor: 'transparent',
        bounds: null,
        imageUrl: null,
        opacity: 1,
        rotation: 0,
        visible: true
    };

    private _img: HTMLImageElement;

    private _mapViewChangeEvent: Microsoft.Maps.IHandlerId;

    /***********************************
    * Constructor
    ***********************************/

    constructor(options: IGroundOverlayOptions) {
        super({
            beneathLabels: (typeof options.beneathLabels === 'boolean') ? options.beneathLabels : true
        });

        this.setOptions(options);
    }

    /***********************************
    * Public Properties
    ***********************************/

    public metadata: any;

    /***********************************
    * Public functions
    ***********************************/

    public clear() {
        this._options = {
            backgroundColor: 'transparent',
            bounds: null,
            imageUrl: null,
            opacity: 1,
            rotation: 0,
            visible: true
        };

        this.setHtmlElement(null);
    }

    public getBackgroundColor(): string | Microsoft.Maps.Color {
        return this._options.backgroundColor;
    }

    public getBounds(): Microsoft.Maps.LocationRect {
        return this._options.bounds;
    }

    public getImageUrl(): string {
        return this._options.imageUrl;
    }

    public getOpacity(): number {
        return this._options.opacity;
    }

    public getRotation(): number {
        return this._options.opacity;
    }

    public getVisible(): boolean {
        return this._options.visible;
    }

    public setOptions(options: IGroundOverlayOptions): void {
        if (options && typeof options.beneathLabels === 'boolean') {
            this._options.beneathLabels = options.beneathLabels;
        }

        if (typeof options.backgroundColor !== 'undefined') {
            this._options.backgroundColor = options.backgroundColor;
        }

        // Remaining logic for setting options...

    }
    
    // More public functions and inherited events go here...

}

Microsoft.Maps.moduleLoaded('GroundOverlaysModule');

Take a look at the web application that incorporates this module:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #myMap {
            height: 100%;
        }
    </style>
</head>
<body>
    <div id="myMap"></div>
    <script>
    var map;
    var groundOverlay;

    function initMap() {
        map = new Microsoft.Maps.Map('#myMap', {
            credentials: 'Your Bing Maps Key',
            zoom: 13,
            center: new Microsoft.Maps.Location(40.740, -74.18)
        });

        Microsoft.Maps.registerModule('GroundOverlaysModule', '../scripts/GroundOverlayModule.js');
        
        // Load module and create GroundOverlay instance...
        
    }
    </script>

    <script async defer src="https://bing.com/api/maps/mapcontrol?callback=initMap"></script>
</body>
</html>

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

The element is not included in any NgModule, or the module has not been properly imported into your module

I am currently working on an angular 4 application and encountering an error: Error:Component HomeComponent is not part of any NgModule or the module has not been imported into your module. My setup includes a HomeModule and a HomeComponent. Now, I am un ...

TypeScript Error: The Object prototype must be an Object or null, it cannot be undefined

Just recently, I delved into TypeScript and attempted to convert a JavaScript code to TypeScript while incorporating more object-oriented features. However, I encountered an issue when trying to execute it with cmd using the ns-node command. private usern ...

Tips for implementing a personalized Circuit Breaker in Node.js that monitors request volume

Currently, I am exploring the most effective way to implement a circuit breaker based on the number of requests served in a Typescript/express application rather than fail percentage. Given that the application is expected to accommodate a large volume of ...

Angular 2 Authentication Service powered by Reactive Extensions

I am currently working on a login form component that includes the following: login.component.ts ngOnInit() { this.authenticationService.loginAttempt .subscribe(() => this.onSuccess(), err => this.onError(err)); } login(credentials) { ...

Unable to generate the 'validator' property on the string 'userForm' while utilizing the component factory

Currently, I am in the process of creating a component factory to generate my login form dynamically. Initially, I encountered an issue where the FormGroup was not recognized by the form where I was introducing my component. After resolving that with the h ...

Is ngOnDestroy executed within Angular services?

Is there a way to confirm if the ngOnDestroy method in my UserServiceService class is functioning properly? I want this service to continue running until the project starts and ends, with ngondestroy method executing once the application (website) is clo ...

testing to see if the value is equal to "null"

I'm having trouble determining if a value is "null." Here is the code snippet I'm working with: Milestone: any={}; constructor(public toastController: ToastController) { this.Milestone.MilestoneType=''; this.Milestone.date=&apo ...

What is the best way to determine a comprehensive map of every sub-store, their functions, and what data they contain?

Summary: Can all actions with their payloads be automatically grouped by sub-store in a composite store using a single type entity (e.g., interface)? I have implemented a Redux store with multiple sub-stores structured as follows: There is an action setA ...

The error caused by Angular v6 is: "TypeError: Unable to access the 'map' property because

It seems that the response JSON is not mapping correctly as expected. Below is the HTML code: <h3>Enter Username</h3> <input (keyup)="search($event.target.value)" id="name" placeholder="Search"/> <ul> <li *ngFor="let package o ...

Instructions for including a class are ineffective

I am trying to dynamically add a class to a div based on two conditions. To achieve this, I have created a custom directive as shown below: import { Directive, HostBinding, Input } from '@angular/core'; @Directive({ selector: '[confirmdia ...

When attempting to parse a file name using a regular expression in TypeScript (or even plain Node.js), the unexpected outcome is a

Looking to extract language information from a filename? Check out this simple construct: The structure of my language.ts model is as follows: export interface Language { language?: string; region?: string; } The function designed for parsing the fi ...

When utilizing a generic schema as an argument in Typescript with Zod, the spread operator can sometimes circumvent the type checking process

My goal is to create a function that validates an object against a Zod schema in TypeScript. However, I have encountered an issue where TypeScript does not seem to properly validate the object when using a spread operator. In the scenario below, the funct ...

`Advancing Angular Bootstrap popover placement in response to varying circumstances`

As a complete novice in the world of Angular, I've done my fair share of research but still can't seem to find what I'm looking for. Here's a snippet of code that I'm working with: @Component({ selector: "help-icon", templateUrl: ...

Can you explain the significance of the colon in this context?

Upon reviewing some SearchKit code snippets (composed with react/jsx and es2015), I came across the following line in a jsx file: const source:any = _.extend({}, result._source, result.highlight) I am curious about the purpose or significance of the colo ...

Steps for disabling Type 'string' does not match Type 'null'. ts (2322) & (2345) error

Is there a way to disable When I write code, I often use a null type check instead of an empty string check. However, TypeScript shows an error stating 'Type 'string' is not assignable to type 'null'.ts(2322)'. If I try to fol ...

Angular function triggered by clicking that takes two parameters

Is there a way to pass two arguments in this method? <tr *ngFor="let match of item.matches " (click)="openMatchContent(match,$event)" openMatchContent(match: any,event:any) {} When I try to run this code, I receive an error statin ...

Automatically Populate Data Table with Email Addresses

After logging into the application, I am using the angular-datatables package from https://www.npmjs.com/package/angular-datatables. The search bar in the datatable auto fills with the email id upon login as shown in the image Data Table. However, I need ...

Encountering issues with Typescript when using absolute paths

After updating a forked repository, I noticed that TypeScript is no longer recognizing absolute paths. Surprisingly, I have not made any changes to my tsconfig.json: { "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, ...

Discover additional features in Angular 4 by reading further

I am struggling with incorporating a "read more" feature in my paragraph on my website. The challenge I'm facing is determining how to trigger the feature to display only when there are more than 5 lines of text. <p>Contrary to popular belief, ...

Choosing radio buttons within rows that contain two radio buttons using ngFor

This section showcases HTML code to demonstrate how I am iterating over an array of objects. <div class="row" *ngFor="let item of modules; let i = index;"> <div class="col-md-1 align-center">{{i+1}}</div> <div class="col-md- ...