Search code examples
javaandroidhere-api

Adding multiple markers in HERE java sdk


I wanted to add multiple markers through different button clicks on HERE maps, however, the 2nd marker that I added did not appear, and tapping the screen multiple times will cause the app to crash.

Here are examples of my code for the tap event declaration:

private MapGesture.OnGestureListener setDestinationListener2 = new MapGesture.OnGestureListener.OnGestureListenerAdapter() {
    @Override
    public boolean onTapEvent(PointF pointF) {
        GeoCoordinate endpoint = map.pixelToGeo(pointF);

        if (destinationMarker != null)
        {
            map.removeMapObject(destinationMarker);
        }
        else
        {
            destinationMarker = new MapMarker(endpoint,image);
            destinationMarker.setAnchorPoint(new PointF(image.getWidth()/2, image.getHeight()));
            map.addMapObject(destinationMarker);

            destination = destinationMarker.getCoordinate();
            map.addMapObject(destinationMarker);
        }
        return super.onTapEvent(pointF);
    }
}; private MapGesture.OnGestureListener addCrowdListener2 = new MapGesture.OnGestureListener.OnGestureListenerAdapter() {
    @Override
    public boolean onTapEvent(PointF pointF) {
        blockedPath = map.pixelToGeo(pointF);
        blockedRoad = RoadElement.getRoadElement(blockedPath, "eng" );

        blocked = new MapMarker(blockedPath, image2 );
        blocked.setAnchorPoint(new PointF(image.getWidth()/2, image.getHeight()));

        map.addMapObject(blocked);
        return super.onTapEvent(pointF);
    }
};

the button's function, that i have declared :

 private void initAddDestinationButton() {
    m_setDetinationButton = (Button) findViewById(R.id.setDestinationButton);

    m_setDetinationButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
             /*
             * Clear map if previous results are still on map,otherwise proceed to creating
             * route
             */
            if (map != null && m_mapRoute != null) {
                map.removeMapObject(m_mapRoute);
                m_mapRoute = null;
            } else
            {
                 if (destinationMarker == null) {
        image = new Image();
        try {
            image.setImageResource(R.drawable.letterx);
        } catch (final IOException e) {
            e.printStackTrace();
        }
    }
    mapFragment.getMapGesture().removeOnGestureListener(addCrowdListener2);
    mapFragment.getMapGesture().addOnGestureListener(setDestinationListener2, 1, true);
            }
        }
    });
}

private void initAddCrowdButton() {
    m_addCrowdButton = (Button) findViewById(R.id.addCrowdButton);

    m_addCrowdButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
             /*
             * Clear map if previous results are still on map,otherwise proceed to creating
             * route
             */
            if (map != null && m_mapRoute != null) {
                map.removeMapObject(m_mapRoute);
                m_mapRoute = null;
            } else
            {
                if (blocked == null) {
        image2 = new Image();
        try {
            image.setImageResource(R.drawable.marker);
        } catch (final IOException e) {
            e.printStackTrace();
        }
    }
    mapFragment.getMapGesture().removeOnGestureListener(setDestinationListener2);
    mapFragment.getMapGesture().addOnGestureListener(addCrowdListener2, 10, true);


            }
        }
    });

}

Solution

  • The issue is the reuse of the mapmarker variable in your code.

    You do this on each tap:

     destinationMarker = new MapMarker(endpoint,image);
     [...]
     map.addMapObject(destinationMarker);
    

    You add destinationMarker to the map and keep a reference of destinationMarker as a member on your side.

    On the second tap, you reuse this reference, to create a new mapmarker instance for destinationMarker, and try to add this to the map. For the map it's the same destinationMarker again. The second marker will not be added, since this reference was already added, even you instance changed.

    You want to keep references to your marker in your code of course (e.g. to remove them later again from the map), so the sugestion is to use a List for all your mapmarker instances like that:

    MapMarker m = new MapMarker(endpoint,image);
    markerList.add(m);
    map.addMapObject(m);
    

    By the way: Beside this issue, also adding the same mapobject twice to the map looks unnecessary to me:

    map.addMapObject(destinationMarker);
    destination = destinationMarker.getCoordinate();
    map.addMapObject(destinationMarker);