How to add custom local marker image to mapbox - reactjs

I'm trying to add the local image as marker to mapbox (mapbox-gl: 2.9.2).
I can add marker from external url like https://placekitten.com/g/30/30, but can't add from local (from my project root dir). I'm using react.
My Attempts: (This shows nothing)
import myCatLogo from './assets/icons/my-cat-logo.png';
const imageCat: any = new Image(20, 20);
imageCat.src = myCatLogo;
map.addImage("myCat", imageCat);
map.addLayer({
id: "marker",
type: "symbol",
source: "datas",
layout: {
"icon-image": "myCat",
// "icon-size": [20, 20],
}
});
My another attempts: (Uncaught (in promise) Error: Not Found at eval)
map.loadImage(myCatLogo, (error, image) => { // the image path is correct!
if (error) throw error;
map.addImage("myCat", image);
});
map.addLayer({
id: "marker",
type: "symbol",
source: "datas",
layout: {
"icon-image": "myCat",
// "icon-size": [20, 20],
}
});
I can add other marker like circle:
map.addLayer({
id: "marker-circle",
type: "circle",
source: "datas",
paint: {
"circle-radius": 4,
"circle-color": "rgb(0, 0, 0)",
},
});

Related

Last line gets cut off when converting HTML page (jsx) to PDF using html2pdf and jspdf

The last line is cut off when converting an HTML (jsx) page to PDF using html2pdf and jspdf. (Reactjs).
and the problem persists despite I use page break with 'avoid-all' mode
there is my code:
const generatePDF = () => {
var element = document.getElementById("report");
var opt = {
margin: [10, 10, 31, 5],
filename: "myfile.pdf",
image: {
type: "jpeg",
quality: 0.98,
},
pagebreak: { mode: ["avoid-all", "css", "legacy"] },
html2canvas: {
scale: 5,
logging: true,
dpi: 96,
useCORS: true,
},
jsPDF: {
orientation: "p",
unit: "mm",
format: "a4",
putOnlyUsedFonts: true,
},
};
html2pdf()
.from(element)
.set(opt)
.toPdf()
.get("pdf")
.save();
};

Adding multiple style layers in Mapbox / React js

I'm using mapbox gl in React to draw polygons on a map. Would like to fill these polygons, and also adjust the border width of the polygons. My understanding is that it is not possible to adjust the border width as a fill property, so a separate line style must be created.
The problem that I am having, is that when I attempt to add an additional style to set the line width, it does not work. Apparently what is happening is that the first style layer is the one that is rendered, and the second one is not, per the code below: "STYLE LAYERS #'S 1 AND 2." I can get the line style to render if I place it in the first position, but then I get no fill layer, and vice-versa.
Any thoughts on this?
useEffect(() => {
if (map.current) return;
map.current = new mapboxgl.Map({
container: mapContainer.current,
style: "mapbox://styles/mapbox/streets-v11",
center: [lng, lat],
zoom: zoom,
});
});
useEffect(() => {
if (!map.current) return;
map.current.on("move", () => {
console.log(map.current.getCenter().lng.toFixed(4));
setLng(map.current.getCenter().lng.toFixed(4));
setLat(map.current.getCenter().lat.toFixed(4));
setZoom(map.current.getZoom().toFixed(2));
});
});
useEffect(() => {
if (!map.current) return;
map.current.on("load", () => {
dataArray.map((item) => {
map.current.addSource(item.name, {
type: "geojson",
data: {
type: "Feature",
geometry: {
type: "Polygon",
coordinates: item.data,
},
properties: {
name: item.name,
},
},
});
//STYLE LAYER #1
map.current.addLayer({
id: item.name,
type: "fill",
source: item.name,
layout: {},
paint: {
"fill-color": "#aaa",
"fill-opacity": 0.25,
"fill-outline-color": "#000",
},
});
//STYLE LAYER #2
map.current.addLayer({
id: item.name,
type: "line",
source: item.name,
layout: {},
paint: {
"line-color": "#000",
"line-width": 2,
},
});
});
});
Each layer needs to have a unique id (see: https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/). So, you could append "-border" to the line layer id.

FeatureLayer - won't render

I have a rather simple code that creates a FeatureLayer where I try to add some client side graphic.
facilitiesLayer = new FeatureLayer({
title: 'Facilities layers',
objectIdField: 'id',
source: [
new Graphic({
geometry: new Point({ longitude: -96.1034353, latitude: 41.5333259 }),
attributes: {
id: 1,
},
}),
],
renderer: new SimpleRenderer({
symbol: new SimpleMarkerSymbol({
size: 32,
color: '#4652C2',
outline: {
color: 'rgba(137,144,215,0.7)',
width: 2,
},
}),
}),
});
mapView.current!.map.add(facilitiesLayer);
after I add the layer to the map I immediately see this in console. If I comment out add layer addition, the map is properly displayed, meaning all of the ESRI stuff is created correct.
How do I find where this conversion fails?
using #arcgis/core 4.18.0

how to add a rectangle on an ui-leaflet map in angular1 programmatically

in HTML my map is defnied as this
<leaflet bounds="map.spatial_bounds_card" layers="map.layers_card" height="200px" ></leaflet>
in the controller, I expand the angular scope, to define bounds and layers. I dont know how to access the leaflet map, in order to add OverlayItems to it. Currently I have created a rectangle, but its not shown on the map.
function Ctrl($scope, leafletBoundsHelpers, leafletDrawEvents) {
var drawnItems2 = new L.FeatureGroup();
angular.extend($scope, {
map: {
spatial_bounds_card: {},
layers_card: {
baselayers: {
osm: {
name: 'OpenStreetMap',
url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
type: 'xyz'
}
}
},
drawOptions: {
position: "bottomright",
draw: {
polyline: false,
polygon: false,
circle: false,
rectangle: {
metric: false,
showArea: true,
shapeOptions: {
color: 'blue'
}
},
marker: false
},
edit: {
featureGroup: drawnItems2,
remove: false
}
},
defaults: {
scrollWheelZoom: false
}
}
});
var bb = L.latLngBounds($scope.filters.spatial.params.southwest, $scope.filters.spatial.params.northeast);
console.log(bb);
var selectedBoundingBox = new L.rectangle(bb,
{
color: 'blue'
});
selectedBoundingBox.addTo($scope.map); // <-- error here
}
I do get this error when running the code:
angular.js:13920 TypeError: t.addLayer is not a function
at e.addTo (leaflet.js:7)
at new FilterSpatialCardCtrl (filter_spatial_card.controller.js:50)
at Object.invoke (angular.js:4718)
at $controllerInit (angular.js:10354)
at nodeLinkFn (angular.js:9263)
at angular.js:9673
at processQueue (angular.js:16383)
at angular.js:16399
at Scope.$eval (angular.js:17682)
at Scope.$digest (angular.js:17495)
In your code there is over head, extra parameters too. Make it as simple as possible.
like:
angular.extend($scope, {
center: {
lat: 54.559322,
lng: -5.767822,
zoom: 14
},
defaults: {
maxZoom: 25,
minZoom: 1,
path: {
weight: 10,
color: '#800000',
opacity: 1
}
}
});
var markersFeatureGroup = new L.FeatureGroup();
leafletData.getMap()
.then(function(map) {
var latlang = L.latLng(50.5, 30.5);
var circleobj = L.rectangle([[54.559322, -5.767822], [54.560900, -5.760000]],{
color: 'blue'
}).bindLabel("Hello World", { direction: 'bottom', clickable: "interactive" });//use left, left, auto,
markersFeatureGroup.addLayer(circleobj);
map.addLayer(markersFeatureGroup);
});
Refer Jsfiddle for more information : http://jsfiddle.net/nidhiarya1245/5hukx0g5/

Angular-Leaflet-directive Custom Marker for geojson data

I'm using Angular-Leaflet-directive and geojson for my markers and I'm having difficulties adding custom markers. I am able to style line/polygons using the style property but no such luck with adding custom icons
e.g. styling line/polygons
angular.extend($scope, {
geojson: {
data: data,
style: {
fillColor: "green",
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7
}
}
});
e.g. attempting to add custom icons for my markers:
var myIcons = {
div_icon: {
type: 'div',
iconSize: [12, 12],
html: '<circle cx="10" cy="10" r="8" stroke="black" stroke-width="1" fill="green" />',
popupAnchor: [0, 0]
},
redPin: {
iconUrl: 'images/mapPinRed.png',
iconSize: [38, 95],
iconAnchor: [22, 94]
}
};
angular.extend($scope, {
geojson: {
data:data,
style: {icon: myIcons.redPin}
}
});
It turns out that in angular-leaflet-directive_v0.7.6 there is no "pointToLayer" for the geojson data, added "pointToLayer:geojson.pointToLayer"
eg angular-leaflet-directive
//...
geojson.options = {
style: geojson.style,
onEachFeature: onEachFeature,
pointToLayer:geojson.pointToLayer
};
It turns out that v0.8 has this feature
e.g. adding the icon
var myIcon = { iconUrl:'images/mapPinRed.png',
iconSize:[25, 25],
iconAnchor:[12, 0]})
};
angular.extend($scope, {
geojson: {
data:data,
style:
function (feature) {return {};},
pointToLayer: function(feature, latlng) {
return new L.marker(latlng, {icon: L.icon(myIcon);
},
onEachFeature: function (feature, layer) {
layer.bindPopup("number: " +feature.properties.something);
}
} //geojson
});

Resources