radMap and the universe of Multiple Pins at the same Coordinates

1 Answer 112 Views
Map
SSirica
Top achievements
Rank 3
Iron
Iron
Iron
SSirica asked on 02 Jun 2022, 02:24 PM

I'm mapping locations.  some times companies have multiple assets at the same address or same Longitude/Latitude.  When this is rendered on the map it shows up as one pin and all the rest get lost in the ether.  I ran across some Kendo example that is supposed to pad the pins.  It doesn't work.  How do we get multiple pins to render at the same location or how do we get one pin to show multiple sets of data?

Map code is pretty simple:

    <telerik:RadMap RenderMode="Lightweight" runat="server" ID="mapSite" Zoom="4" CssClass="MyMap Rounded" Width="100%" Height="100%">
        <DataBindings>
            <MarkerBinding DataShapeField="Shape" DataTitleField="SITE_CITY" DataLocationLatitudeField="Latitude" DataLocationLongitudeField="Longitude" />
        </DataBindings>
        <LayersCollection>
            <telerik:MapLayer Type="Tile" Subdomains="a,b,c"
                UrlTemplate="https://#= subdomain #.tile.openstreetmap.org/#= zoom #/#= x #/#= y #.png"
                Attribution="">
            </telerik:MapLayer>
        </LayersCollection>
    </telerik:RadMap>

Code behind:

Binding code:

            Dim res = From x In db.SITEs
                      Where x.COMPANY.COMPANY_CODE.Equals(Session("Market").ToString)
                      Select New clsSiteData With {
                          .Shape = "PinTarget",
                          .SITE_ID = x.SITE_ID,
                          .SITE_CODE = x.SITE_CODE,
                          .SITE_NAME = x.SITE_NAME,
                          .SITE_ADDRESS_1 = x.SITE_ADDRESS_1,
                          .SITE_ADDRESS_2 = x.SITE_ADDRESS_2,
                          .SITE_CITY = x.SITE_CITY,
                          .STATE_CODE = x.STATE.STATE_CODE,
                          .POSTAL_CODE = x.SITE_POSTAL_CODE,
                          .BUILDING_ID = x.SITE_BUILDING_IDENTIFIER,
                          .PROPERTY_ID = x.PROPERTY_CODE.PROPERTY_CODE,
                          .Latitude = If(x.SITE_MAP_LAT, 0),
                          .Longitude = If(x.SITE_MAP_LON, 0)
                          }

            mapSite.DataSource = res.ToList
            mapSite.DataBind()

ItemDataBound:

Private Sub mapSite_ItemDataBound(sender AsObject, e As MapItemDataBoundEventArgs) Handles mapSite.ItemDataBound Dim htmlTemplate AsStringTry hlAssInv.Visible = CType(ViewState("Asset"), Boolean) htmlTemplate = getInnerHTML(tblTemplate) Dim marker As MapMarker = TryCast(e.Item, MapMarker) If marker IsNothingThenReturnEndIfDim item As clsSiteData = TryCast(e.DataItem, clsSiteData) marker.TooltipSettings.Content = [String].Format(htmlTemplate, item.SITE_CODE, item.SITE_NAME, item.SITE_ADDRESS_1, item.SITE_ADDRESS_2, item.SITE_CITY, item.STATE_CODE, item.POSTAL_CODE, item.BUILDING_ID, item.PROPERTY_ID, item.SITE_ID) Catch ex As Exception Dim xxx AsString = ex.Message.ToString End Try

End Sub


1 Answer, 1 is accepted

Sort by
0
Accepted
Peter Milchev
Telerik team
answered on 07 Jun 2022, 10:17 AM

Hello,

You have probably encountered this forum thread where the padding is discussed.

If that is correct, the snippet needs a little adjustment as now the TOP style comes as a string with format "300px" so you need to convert it to a number before applying any math operations to it. 

Here is how this would go for a RadMap:

<telerik:RadMap RenderMode="Lightweight" runat="server" ID="RadMap1" Zoom="2" CssClass="MyMap">
    <CenterSettings Latitude="23" Longitude="10" />
    <LayersCollection>
        <telerik:MapLayer Type="Tile" Subdomains="a,b,c"
            UrlTemplate="https://#= subdomain #.tile.openstreetmap.org/#= zoom #/#= x #/#= y #.png"
            Attribution="&copy; <a href='http://osm.org/copyright' title='OpenStreetMap contributors' target='_blank'>OpenStreetMap contributors</a>.">
        </telerik:MapLayer>
    </LayersCollection>
    <MarkersCollection>
        <telerik:MapMarker Shape="PinTarget" Title="Palo Alto">
            <TooltipSettings Content="US - Palo Alto, CA"></TooltipSettings>
            <LocationSettings Latitude="37.444610" Longitude="-122.163283" />
        </telerik:MapMarker>
        <telerik:MapMarker Shape="PinTarget" Title="Palo Alto 2">
            <TooltipSettings Content="US - Palo Alto 2, CA"></TooltipSettings>
            <LocationSettings Latitude="37.444610" Longitude="-122.163283" />
        </telerik:MapMarker>
    </MarkersCollection>
    <ClientEvents OnLoad="OnLoad" />
</telerik:RadMap>
<script>
    function OnLoad(sender, args) {
        var map = sender.get_kendoWidget();
        var markers = map.markers.items;
        var prev;
        var curr;
        for (var i = 0; i < markers.length; i++) {
            curr = markers[i]
            if (prev && prev.options.location[0] === curr.options.location[0] && prev.options.location[1] === curr.options.location[1]) {
                console.log(curr.element.css('top'));
                curr.element.css({ top: Number.parseInt(curr.element.css("top")) - 10 })
            }
            prev = curr;
        }
    }
</script>

Regards,
Peter Milchev
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

SSirica
Top achievements
Rank 3
Iron
Iron
Iron
commented on 07 Jun 2022, 01:54 PM | edited

Thank you for the response Peter.  At least your example worked...to a certain extent.  The 2 pins only show initially.  As soon as you zoom in one of the Markers goes away.  That's no bueno.  I will try your example in my real world scenario and see what happens.  

Thanks again for the starter code to get going. 

Peter Milchev
Telerik team
commented on 10 Jun 2022, 10:58 AM

You are correct, the zoom is resetting the positioning of the map. In such a case, you can extract the logic and just pass the map to the new function when you call it from the OnLoad and OnZoomEnd client-side events:

function FixMarkers(map) {

    var markers = map.markers.items;
    var prev;
    var curr;
    for (var i = 0; i < markers.length; i++) {
        curr = markers[i]
        if (prev && prev.options.location[0] === curr.options.location[0] && prev.options.location[1] === curr.options.location[1]) {
            console.log(curr.element.css('top'));
            curr.element.css({ top: Number.parseInt(curr.element.css("top")) - 10 })
        }
        prev = curr;
    }
}
function OnZoomEnd(ev) {
    FixMarkers(ev.sender)
}
function OnLoad(sender, args) {
    FixMarkers(sender.get_kendoWidget());
}

SSirica
Top achievements
Rank 3
Iron
Iron
Iron
commented on 14 Jun 2022, 02:20 PM

Worked like a charm with one minor alteration:

                curr.element.css({ top: Number.parseInt(curr.element.css("top")) - (10 * i) })

With that change there can be more than one location with the same Lat/Lon and they will all just cascade.  Thanks again.  

Tags
Map
Asked by
SSirica
Top achievements
Rank 3
Iron
Iron
Iron
Answers by
Peter Milchev
Telerik team
Share this question
or