I am Trying to Implement OSM and Mapnik.
My requirement is to show a Custom map to the end user(First layer of Basic Map and Second Layer of Map generated by the Data).
I've Started by implementing Demo Examples from Mapnik but didn't get enough Idea.
Here is what I've tried,
App.js
var mapnik = require('mapnik');
var fs = require('fs');
/// Register fonts and datasource plugins
mapnik.register_default_fonts();
mapnik.register_default_input_plugins();
var map = new mapnik.Map(1280, 720);
map.load("./stylesheet.xml", function(err, map) {
if(err != null){
console.log(err)
return
}
map.zoomAll();
var im = new mapnik.Image(1280, 720);
map.render(im, function(err, im) {
im.encode("png", function(err, buffer) {
fs.writeFile("map.png", buffer);
});
});
});
Stylesheet.xml
<Map background-color="white" srs="+init=epsg:4326">
<Style name="My Style">
<Rule>
<PolygonSymbolizer fill="#f2eff9" />
<LineSymbolizer stroke="rgb(50%,50%,50%)" stroke-width="0.1" />
</Rule>
</Style>
<Style name="countries">
<Rule>
<PolygonSymbolizer fill="blue" />
<LineSymbolizer stroke="rgb(50%,50%,50%)" stroke-width="0.4" />
</Rule>
</Style>
<Layer name="world" srs="+init=epsg:4326">
<StyleName>countries</StyleName>
<Datasource>
<Parameter name="file">../data/India/IND_adm3.shp</Parameter>
<Parameter name="type">shape</Parameter>
</Datasource>
</Layer>
</Map>
Can anyone please guide me in this. How can I achieve Requirement ??
Any help will be appreciated.
Related
This is using the https://github.com/visgl/react-map-gl fork.
Using vanilla JS, you use the 'load' callback to add a Source and then set the Terrain.
I was able to replicate this using React and useEffect, but the solution doesn't feel right. How does one properly do this in React?
first a Source should be returned as a child of the map:
{ Source } from "react-map-gl";
<Map ...>
<Source
id="mapbox-raster-dem"
type="raster-dem"
url="mapbox://mapbox.mapbox-terrain-dem-v1"
tileSize="512"
maxzoom="14"/>
</Map>
and now you can specify the Terrain style inside the Map component:
terrain={{
source: "mapbox-raster-dem",
exaggeration: 2,
}}
full code:
const MapInstance = () => {
return (
<Map
...
terrain={{
source: "mapbox-raster-dem",
exaggeration: 2,
}}
>
<Source
id="mapbox-raster-dem"
type="raster-dem"
url="mapbox://mapbox.mapbox-terrain-dem-v1"
tileSize="512"
maxzoom="14"
/>
</Map>
);
};
I have a map with an icon marked derived from a kml file. The kml file is:
<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>Dove.kml</name>
<Style id="Dove6">
<IconStyle id="DoveRIconStyle">
<Icon>
<href>https://wcsb.nz/wellringers/dove6.bmp</href>
</Icon>
</IconStyle>
<LabelStyle>
<color>9fffffff</color>
<scale>0.67</scale>
</LabelStyle>
</Style>
<Placemark>
<name>Ab Kettleby</name>
<styleUrl>#Dove6</styleUrl>
<Point>
<coordinates>-0.92747,52.79858</coordinates>
</Point>
</Placemark>
<Placemark>
<name>Asfordby, Leics, 6, 12cwt, Mon</name>
<styleUrl>#Dove6</styleUrl>
<Point>
<coordinates>-0.95214,52.76339,0</coordinates>
</Point>
</Placemark>
</Document>
</kml>
I want to show the information in in a bubble when the icon is clicked. The code I have written is :
const defaultLayers = platform.createDefaultLayers();
const map = new H.Map(document.getElementById('map'),
defaultLayers.vector.normal.map, {
center: { lat: 52.79858, lng: -0.92747 },
zoom: 15,
pixelRatio: window.devicePixelRatio || 1
});
window.addEventListener('resize', () => map.getViewPort().resize());
const behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
const ui = H.ui.UI.createDefault(map, defaultLayers);
let reader = new H.data.kml.Reader('doveshort1.kml');
reader.parse();
kml = reader.getLayer();
map.addLayer(kml);
kml.getProvider().addEventListener('tap', function(ev) {
const info = ev.target.getData();
let content = '<b>' + info.name + '</b><br/>';
let bubble = new H.ui.InfoBubble(ev.target.getPosition(), {
content: content
});
ui.addBubble(bubble);
});
Sadly nothing happens when I click the icon.
The page is at https://wcsb.nz/wellringers/kmltest.html.
Any help gratefully received.
I can see that you are using ev.target.getPosition() inside the tap event handler. The function you want to use is evt.target.getGeometry() instead.
So your code snippet will look something like this.
kml.getProvider().addEventListener('tap', function (ev) {
if (ev.target instanceof H.map.Marker) {
const info = ev.target.getData();
let content = '<b>' + info.name + '</b><br/>';
let bubble = new H.ui.InfoBubble(ev.target.getGeometry(), {
content: content
});
ui.addBubble(bubble);
}
});
I'm wondering how I can pass non-string data between two pages in Ionic 5 using ReactRouter.
All solutions I could find used Ionic and Angular or just passed one string as URL parameter.
These are my components so far:
App.tsx
const App: React.FC = () => {
return (
<IonApp>
<IonReactRouter>
<IonSplitPane contentId="main">
<Menu />
<IonRouterOutlet id="main">
<Route path="/page/Home" component={Home} exact />
<Route path="/page/DataEntry" component={DataEntry} exact />
<Route path="/page/Request" component={Request} exact />
<Route path="/page/ResultMap" component={ResultMap} exact />
<Redirect from="/" to="/page/Home" exact />
</IonRouterOutlet>
</IonSplitPane>
</IonReactRouter>
</IonApp>
);
};
Page 1 here collects user input data (strings, objects, arrays) and I want to call the route '/page/ResultMap' on Button click and pass the data, so the next page can handle it:
<IonGrid>
<IonRow>
<IonCol class="ion-text-center">
<IonButton text-center="ion-text-center" color="primary" size="default" routerLink='/page/ResultMap'>Erkunden!</IonButton>
</IonCol>
</IonRow>
</IonGrid>
Page 2, which should receive the Data:
const ResultMap: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonMenuButton />
</IonButtons>
<IonTitle>Map</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
</IonContent>
</IonPage>
);
};
I understand the React principle about props and state, I just dont know how to combine it with Ionic in this case.
I appreciate your help!
Edit:
As suggested I changed the button onClick like this:
<IonButton text-center="ion-text-center" color="primary" size="default" onClick={e => {
e.preventDefault();
history.push({
pathname: '/page/ResultMap',
state: { time: transportTime }
})}}>
And try to receive the data on the ResultMap page like this:
let time = history.location.state.time;
But I get the error:
Object is of type 'unknown'. TS2571
7 | let history = useHistory();
8 |
> 9 | let time = history.location.state.time;
| ^
How do I access the passed object on the new page?
as for react-router I know you can use this:
history.push({
pathname: '/template',
state: { detail: response.data }
})
in this situation you can pass data without URL Params
can also use history.replace
if you redirect and want the back button work properly to the end user
and for the history do the following
let history = useHistory();
Check this link for a great understand how to implement the useHistory type
I am very new to react, an i have a use case like, getting the books details in a API response with the image. I need to iterate over the response and I need to display the image.
as suggested displaying binary data as image below is the code i have used for this. But image is not displayed. Any suggestions would be appreciated. What Am i doing wrong?
<View>
<FlatList data={books} renderItem={
data => {
console.log("data is -? " + books.author);
//const buffer = Buffer.from(data.item.image.data, 'binary').toString('base64');
/* let image = btoa(
new Uint8Array(data.item.image.data)
.reduce((d, byte) => d + String.fromCharCode(byte), '')
);*/
const encoded = data.item.image.data;
<View style={styles.imageContainer}>
<Image
source={{
uri: `data:image/jpeg;base64,${encoded}`
} }
//source="{URL.createObjectUrl(encoded)}"
style={styles.stretch}
/>
</View>
}
} />
</View>
Here am sharing the solution how did solve the problem, hope this might help someone. Just sharing the working code.
<FlatList data={books} keyExtractor={(item, index) => item.id.title+index}
renderItem={({ item }) =>
<Item title={item} />
} />
function Item({ title }) {
let ed = 'data:image/png;base64,' + title.image.data;
return (
<View>
<Image source={{ uri: ed }} /></View>
);
}
I wanted to pass the value to filter option in run-time. Below is the code, I just tried and it is not working. can anyone please tell me that, how can I achieve this option ?
<l:VerticalLayout width="100%" id="idRENT_CAR_DET"
content="{path:'/Trip_section/Rental_det',
filters : { path : 'TripId',
operator :'EQ',
value1: '{ path :'Trip_section>/TripId'}' } }" >
<l:Grid defaultSpan="L2 M6 S6" minWidth="1024">
<m:Input value="{From}" type="Date"/>
<m:Input value="{To}" type="Date" />
<m:HBox>
<m:Button id="idRCBTN" icon="sap-icon://sys-add"/>
<m:Button icon="sap-icon://sys-cancel" />
</m:HBox> </l:Grid> </l:VerticalLayout>
I haven't ran your code but your xml formatting is wrong.
You must use different characters for '
'{ path :'Trip_section>/TripId'}'
Maybe it would be the best if you apply the filter to your view in your controller.
var aFilter = [];
var sQuery = oEvent.getParameter("query");
if (sQuery) {
aFilter.push(new Filter("ProductName", FilterOperator.Contains, sQuery));
}
var oVerticalLayout = this.getView().byId("theGivenId...");
var oBinding = oVerticalLayout.getBinding("content");
oBinding.filter(aFilter);
Maybe the binding isn't available in the onInit function.
I wish you good luck.