Rails 7 importmap leaflet-css images path fix? - javascript

What I'd like to do:
I would like to have a leaflet layers control in my Rails 7 app.
What I get:
Leaflet works fine, but the control appears without the icon, like this:
and in the browser console I get this error:
GET http://my_ip/trial_models/undefined/layers.png 404 (Not Found)
and in my server log the error is presented like this:
Started GET "/trial_models/undefined/layers.png" for my_ip at 2022-03-30 06:50:43 +0000
ActionController::RoutingError (No route matches [GET] "/trial_models/undefined/layers.png"):
I've replaced the actual ip address with "my_ip". The 'undefined' is really there in the error messages.
How I did it:
First I created a Rails 7 app and imported leaflet like this:
./bin/importmap pin leaflet
./bin/importmap pin leaflet-css
I then created a TrialModel using standard rails g scaffold. I then added the following stimulus div in trail_models\show.html.erb :
<div data-controller="trialmap" data-trialmap-target="trial" style="height:600px" class="leaflet-container"></div>
I created \app\javascript\controllers\trialmap_controller.js with the following contents:
import { Controller } from "#hotwired/stimulus";
import "leaflet-css";
export default class extends Controller {
static targets = [ "trial" ]
connect(){
import("leaflet").then( L => {
this.map = L.map(this.trialTarget).setView([ 51.472814, 7.321673 ], 14);
var base_map = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap | SwmmGo',
transparency: true,
opacity: 0.5
}).addTo(this.map);
var landMap = L.tileLayer('http://{s}.tile.thunderforest.com/landscape/{z}/{x}/{y}.png', {attribution: 'attributions'});
var layersControl = new L.Control.Layers({
"Street Map": base_map,
"Landscape": landMap
});
this.map.addControl(layersControl);
});
}
disconnect(){
this.map.remove()
}
}
What I've explored:
I tried downloading leaflet-css like this:
./bin/importmap pin leaflet-css --download
but same result.
I can see that there is a references background-image:url(images/layers.png); in the imported/ downloaded file vendor/javascript/leaflet-css.js. But there doesn't seem be any images folder anywhere like vendor/javascript/images/ or the like.
The stringify version of L.Control.prototype.options is just {"position":"topright"}.
I tried setting L.Control.prototype.options.iconUrl = "layers.png" (and "/layers.png") in the js controller and then placing a manually downloaded layers.png file in public. But this changed neither the results nor the error messages.
My questions:
How can I get the icon to show and the error to disappear? (a work-around would be ok too)
What is the "correct way" to handle assets and asset paths which css files reference when using importmap?
Any help would be much appreciated! Thanks!

I had similiar problems when using markers, my solution was not using leaflet-css and just using the leaflet CSS from CDN

I did like Luis - put the leaflet.css downloaded from https://leafletjs.com in vendor/assets/stylesheets and the images in public/images - that solved my issues with broken marker/layer images

Don't use leaflet-css, it bundles both the leaflet css and an ancient version (0.6.4) of the leaflet js code. It seems that the other answers here are on target - rails importmaps are for js only; if you are working with a third-party lib that has its own css assets you will need to handle those separately either through a CDN or by downloading them and placing them alongside your other css assets.

Related

D3 library in R?

I am working with the "r2d3" library in R (https://www.rstudio.com/blog/r2d3-r-interface-to-d3-visualizations/) - as I understand, this library is intended to perform javascript based data visualizations in R.
I would like to try and run the following visualization in R : https://rstudio.github.io/r2d3/articles/gallery/bubbles/
I loaded the data into R:
library(r2d3)
library(ggraph)
data(flare)
Then, I copied the entire "bubbles.js" script into a new R Markdown editor and clicked "knit to html". Then, I got the following output:
Clearly, I am doing something wrong.
Can someone please show me how to fix this?
Thanks!
Note: I tried running the following code in R Console:
r2d3(data = flare, d3_version = 4, script = "bubbles.js")
And this is the error I got:
/../as I understand, this library is intended to perform javascript
based data visualizations in R /../
It's more of an interface for existing D3 visualizations.
https://rstudio.github.io/r2d3/index.html provides fairly good overview of the process, you should go through that first.
To get that gallery sample working, you first prepare a working directory where you have:
flare.csv
bubbles.js
Once you have made sure your working dir is the same where those files are (getwed() / setwd()), running
library(r2d3)
r2d3(data = read.csv("flare.csv"), d3_version = 4, script = "bubbles.js")
in console / script / rmd should render those bubbles.
Or you could just clone the repo and have all sample files including Rmd-s - https://github.com/rstudio/r2d3/tree/main/vignettes/gallery/bubbles
RStudio provides some support for D3 scripts, so you can also go through File > New File > D3 Script and paste the bubbles.js content there or open existing bubbles.js file. Assuming you have flare.csv file in working directory, you can click on a Preview to have it rendered in Viewer pane. That's what the
// !preview r2d3 data = read.csv("flare.csv"), d3_version = 4
line in js script header is there for.

Avoid prefixing img src for data:image url #ionic-native/google-maps

I have an Ionic Cordova application running on both iOS and Android with Angular. I use the #ionic-native/google-maps plugin to display a map along with different kind of markers. Until now, I have only used static markers from .png files which works perfectly and expected.
However, I have come to a point where I want the users to see other markers that are dependent on a state in the code. To solve this, I have created a SVG template as a string where I replaces some value to reflect the parameters I want to be displayed. I then perform some regex on the string to to encode it correctly (similar to XMLSerializer.serializeToString()) before base64 encode it and prefixing with data:image/svg+xml;base64,. This way, I have an data URL to be used with the src tag in the marker img attribute through the Marker's MarkerOption icon url property which result in:
const icon = { url: 'data:image/svg+xml;base64,PD9 (...)', size: { width: 38, height: 40 }, anchor: [0, 40] }
const marker: Marker = this.map.addMarkerSync({
icon,
(...)
})
According to the cordova-plugin-googlemaps documentation (see here), this is a valid way to specify an icon for a marker. However, Ionic tries by default to fetch this url from http://localhost:8100 which naturally will fail. I end up with the following error message in console:
map_0_24694408793: "Can not load image from 'http://localhost:8100/data:image/png;base64,Pd9 (...)'
I have tried different approaches as well without any results. Such as file://, /, // and window.Ionic.WebView.convertFileSrc() (as for normal files). I have also tried to input the url directly to the icon parameter: icon: icon.url
Is there by any chance possible to tell Ionic not to look for that source when it contains an data:image URI that I have overlooked?
Versions:
#ionic-native/google-maps: 5.5.0
cordova-plugin-googlemaps: 2.7.1
Ionic CLI version: 6.16.3
Ionic Framework: #ionic/angular 5.2.3
Cordova Platforms: android 9.1.0, ios 6.2.0
angular: 9.1.6

How to load a custom .pbf file in ngx-openlayers

I was able to load maps using the ngx-openlayers with the following code
<aol-map [width]="'100%'" [height]="'100%'">
<aol-view [zoom]="zoom">
<aol-coordinate [x]="5" [y]="45" [srid]="'EPSG:4326'"></aol-coordinate>
</aol-view>
<aol-layer-tile [opacity]="opacity">
<aol-source-osm></aol-source-osm>
</aol-layer-tile>
<aol-layer-vector [opacity]="opacity">
<aol-source-vector>
<aol-feature>
<aol-geometry-point>
<aol-coordinate [x]="5" [y]="45" [srid]="'EPSG:4326'"></aol-coordinate>
</aol-geometry-point>
<aol-style>
<aol-style-circle [radius]="10">
<aol-style-stroke [color]="'black'" [width]="width"></aol-style-stroke>
<aol-style-fill [color]="'green'"></aol-style-fill>
</aol-style-circle>
</aol-style>
</aol-feature>
<aol-feature>
<aol-geometry-point>
<aol-coordinate [x]="5.1" [y]="45.1" [srid]="'EPSG:4326'"></aol-coordinate>
</aol-geometry-point>
<aol-style>
<aol-style-icon [src]="'assets/marker.png'" [anchor]="[0.5, 1]" [anchorXUnits]="'fraction'" [anchorYUnits]="'fraction'" [scale]="0.1"
[anchorOrigin]="'top-left'">
</aol-style-icon>
</aol-style>
</aol-feature>
</aol-source-vector>
</aol-layer-vector>
</aol-map>
My issue is I want to load a custom map location that I have served on my local machine using MapTile server on http://localhost:8090/tileserver.php#trails/ol3 URL.
Now the XYZ URL from the above server is (http://localhost:8090/tileserver.php?/index.json?/trails/{z}/{x}/{y}.pbf)
How can I load this map using the ngx-openlayers packkage
I have tried to use this but it is not working
<aol-map [width]="'500px'" [height]="'300px'">
<aol-interaction-default></aol-interaction-default>
<aol-control-defaults></aol-control-defaults>
<aol-control-fullscreen></aol-control-fullscreen>
<aol-layer-tile>
<aol-source-osm></aol-source-osm>
<aol-source-xyz [url]="'http://localhost:8090/tileserver.php?/index.json?/trails/{z}/{x}/{y}.pbf'">
</aol-source-xyz>
</aol-layer-tile>
<aol-view [zoom]="12">
<aol-coordinate [x]="6.47" [y]="53.44" [srid]="'EPSG:4326'"></aol-coordinate>
</aol-view>
</aol-map>
So yeah I'm about to answer my own question cause it might help someone in the future.
The Basics
There are two broad classifications for maps from OSM (OpenStreetMap)
1.Raster Format: This one is the raster image (PNG, JPEG, SVG ...) tiles for the map. This format can be compressed and put it to .mbtiles format.
You can use tools like mbuilt to extract the contents into the tms, wsm or XYZ folder structure. This one is the easy and faster option.
Vector Format: This one is a Vector file format it can have multiple file type like .pbf inside it. It can also be compressed into a .mbtiles file. we need a tile server to render the contents of the vector files.
Tile server GL is a tile server to serve both vector/raster map files (mbtiles)
After solving the offline hosting issue, I have used a default leaflet.js package for angular and everything worked fine without an issue.
I used OpenMaptiles map files to host them using the tileserver-gl

How to parse and load tiles from .mbtiles?

I've been trying to parse and load tiles from a .mbtiles file using the mbtiles-php script without much success. Followed the instructions on the repository site.
Installed a foo.mbtiles file on the same folder as .htaccess and tileserver.php. Also, this is how I have been loading the tiles:
var map = $(window).load(function() {
L.mapbox.map('map', './tiles/foo.mbtiles')
.setView([74.2343, -54.43534], 14);
});
Here's the console log
Since L.mapbox.map does not parse .mbtiles, changed to L.tileLayer. Here's the new code:
$(window).load(function() {
var map = L.map('map').setView([74.2343, -54.43534], 14);
L.tileLayer('./tiles/foo.mbtiles/{z}/{x}/{y}.png', {
maxZoom: 19
}).addTo(map);
});
I'm now getting several of these on my console:
Failed to load resource: the server responded with a status of 404 (Not Found)
http://43.000.00.0/tiles/foo.mbtiles/13/3888/3139.png
I had .htaccess usage disabled on my server. After enabling it, I'm now getting blank tiles
The second parameter for L.mapbox.map accepts one of four things, a Mapbox.com Map ID, a comma-delimited list of Mapbox.com IDs, a TileJSON url or a TileJSON object. You are passing none of those, but a location to a MBTiles file.
If you're going to be serving tiles from a MBTiles file from a PHP server, you should be adding a l.tileLayer like L.tileLayer('http://$MY_LOCAL_SERVER_LOCATION/{z}/{x}/{y}.png').addTo(map);
This obviously depends on your local PHP configuration.
The following code seems to work fine with Leaflet:
$(window).load(function() {
var map = L.map('map').setView([74.2343, -54.43534]);
L.tileLayer('./tiles/foo/{z}/{x}/{y}.png', {
maxZoom: 15
}).addTo(map);
});
PDO and GD must be enable on your server, as well as .htaccess

Values for global Javascript variable is wrong at the momemt to get it

I am ready with a port from a php mvc application to asp.net mvc (using a lot of javascript and google maps). The application works quite well on my development machine (Win 7 + IIS 7). But the problems start on production server. for some reason i have a javascript file wich is not working well when i am using it from my production server.
i.e. I have my view where i load all the data from db and and after that I put this on an global variable array called global_sites_am. Each row in the array contains attributes like latitud ,longitud and name.... After that this array is readed from the js file called maps.js.
var position = new google.maps.LatLng(global_sites_am[i].latitud,global_sites_am[i].longitud);
addMarker(position,global_sites_am[i].name,i);
For some reason this piece of code work fine on my development machine but it doesn't when i have installed the app on production server.
I.E. On Development machine : global_sites_am[0].latitud = 45,6789566 and global_sites_am[i].longitud=72,69452015
But on Production machine : global_sites_am[0].latitud = 45 and global_sites_am[i].longitud=72
What i am doing wrong?
Update: Here is How I load the value from the db to the javascript file:
global_sites_am[count]=new Object();
global_sites_am[count].name='<%=site.Name%>';
global_sites_am[count].latitud=<%=site.Latitud%>;
global_sites_am[count].longitud=<%=site.Longitud%>;
This is one of my properties:
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public global::System.Double Latitud
{
get
{
return _Latitud;
}
set
{
OnLatitudChanging(value);
ReportPropertyChanging("Latitud");
_Latitud = StructuralObject.SetValidValue(value);
ReportPropertyChanged("Latitud");
OnLatitudChanged();
}
}
Some debug info from Chrome: http://oi49.tinypic.com/2j4q7p4.jpg. In the image you will see that the values at the moment to load in the page are correct, but at the moment to read them are wrong.
Finally the problem was solved using the next line on the web.config:
globalization uiCulture="en-US" culture="en-US"

Categories

Resources