https://cdn.discordapp.com/attachments/286612533757083648/96...
00 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
10 00 00 01 00 00 00 01 00 01 03 00 00 00 66 bc 3a |.............f�:|
20 25 00 00 00 03 50 4c 54 45 b5 d0 d0 63 04 16 ea |%....PLTE���c..�|
30 00 00 00 1b 49 44 41 54 68 81 ec c1 01 0d 00 00 |....IDATh.��....|
40 00 c2 a0 f7 4f 6d 0f 07 14 00 00 00 00 00 00 00 |. �Om..........|
50 c0 b9 01 |��.|
Although technically invalid, it still renders fine in Firefox, Chrome, and Safari.Edit: 87 -> 83 bytes
Edit2: Maybe in a couple of years time, we can use JPEG-XL instead (only 22 bytes, without any hacks!):
data:image/jxl;base64,/wp/QCQIBgEALABLOEmIDIPCakgSBg==https://en.wikipedia.org/wiki/JPEG_XL
Preliminary support in Firefox and Chromium nightly/testing builds already. I share your hope that we can start to use it in the next couple years. Looking at you, Safari ;)
But, yeah, we had all those things in something that was actually in major browsers, 22 years ago.
To see them, enable flag in chrome: chrome://flags/#enable-jxl
WebP is 38 bytes, and is already supported by browsers.
00000000 52 49 46 46 24 00 00 00 57 45 42 50 56 50 38 4c |RIFF$...WEBPVP8L|
00000010 18 00 00 00 2f ff c0 3f 00 07 50 e8 d6 16 ba ff |..../???..P??.??|
00000020 01 00 45 fa ff 9f 22 fa 9f fa df 7f |..E??."?.??.|
data:image/webp;base64,UklGRiQAAABXRUJQVlA4TBgAAAAv/8A/AAdQ6NYWuv8BAEX6/58i+p/6338=
Maybe can be made smaller, I just used cwebp -z 9.When I learned HTML the syntax was sooo particular.
Now (our pretty much since then) anything goes and I love it
Natural evolution of protocols
Protocols with miltiple implementations are way more strict, because you can't feasibly test your quirky approach on every implementation, and the chance they will all be as forgiving is slim.
47 49 46 38 39 61 01 00 01 00
00 ff 00 2c 00 00 00 00 01 00
01 00 00 02 00 3b
http://probablyprogramming.com/2009/03/15/the-tiniest-gif-ev...
P1
1 1
1
is a 9 byte 1 × 1 pixel black image in portable bitmap format (https://en.wikipedia.org/wiki/Netpbm#File_formats). Consumers of such files likely will know how to scale them to 256 × 256 pixels. The trailing newline may not even be necessary. If so, it would become 8 bytes.Gray 1 X 1 pixel images in binary portable graymap format have the same size. To get a non-gray RGB color, you’ll need two more bytes in binary portable pixmap format.
71 6f 69 66 00 00 00 01 00 00 00 01 04 00 | 14 byte header
00 | QOI_OP_INDEX
00 00 00 00 00 00 00 01 | end marker
Similarly the 103 byte png in the article would be [EDIT] This is incorrect, see below 71 6f 69 66 00 00 01 00 00 00 01 00 04 00 | 14 byte header
fe b7 d0 d0 | QOI_OP_RGB, RGB color,
fd fd fd fd c6 | QOI_OP_RUN for 62+62+62+62+7
00 00 00 00 00 00 00 01 | end marker
[0]: https://qoiformat.org/qoi-specification.pdf[EDIT] I realized that we actually run into one of QOI's drawbacks if we were to encode the 103 byte png in the article, as we actually need to repeat the pixel 65535 times, so we'd have floor(65535/62)=1057 QOI_OP_RUN bytes followed by another QOI_OP_RUN to repeat the last pixel. Here it's pretty clear that the QOI spec missed out on special handling of repeated QOI_OP_RUN operators, as long repetitions could have been handled in far fewer bytes.
This works because modern browsers have support for progressively rendering images that are still being downloaded - as a result, truncation is also handled gracefully.
However, this alone results in rendering errors - the last few rows of pixels end up missing, like this:
https://cdn.discordapp.com/attachments/286612533757083648/96...
I don't know the precise reason for this, but I believe the parsing state machine ends up stalling too soon, so I threw some extra zeroes into the IDAT data to "flush" the state machine - but not enough to increase the file size.
[1] https://docs.mapbox.com/data/tilesets/guides/access-elevatio...
What's funny is that you can parse a GeoTIFF as a .tiff most of the time but not always. I had fun debugging that :). Java's BufferedImage understandably doesn't directly support negative pixel values haha
To me (working in the VFX industry with EXR being the predominant HDR format), it's interesting that something that compresses a lot better than TIFF (i.e. EXR) hasn't won over in the GIS space, but I believe that's mostly momentum as well as the fact EXR doesn't natively support 64-bit float, but then neither does TIFF really (it's an extension), and the same could be done with EXR (extend the formats it supports).
However I don’t know of any DEM tile apis that provide these sorts of PNGs but it sounds like a fun project!
Edit: I found this StackExchange post which shows how to generate 16-bit PNGs with gdal https://gis.stackexchange.com/questions/246934/translating-g...
Any value below sea level I set to 0. Any value above sea level I converted using the following formula:
scaled = elevation * Math.floor[(256 * 256) / (8849 - 0)];
top_byte = scaled / 256;
bottom_byte = scaled % 256;
This provides accuracy to 1/7th of a meter compared to 1/10th of a meter with Mapbox but the tile size went from 104KB -> 25KB. For applications that can ignore elevations below sea level, this is a huge savings.
Edit: the top level tile has a lot of ocean so the size savings are better than average. On a tile with no water, the savings appear to be around 50%.
Edit: a link to a mapbox-gl-js discussion on the use of custom dems/encodings (after which anything is possible): https://github.com/mapbox/mapbox-gl-js/issues/10775
Worth noting DEMs are moving away from tiled formats recently. Mainly to COG (Cloud Optimised Geotiff) which isn't the most efficient but is a simple tweak to a file format already broadly adopted. There's a few others out there aiming for efficency at scale too - ESRI has CRF and MRF for instance, but nothing has become industry standard other than COG yet.
CSS is a thing as well, could just use CSS to force all tiles to the same size, regardless of the image data in them. Something like:
.map img {
width: 256px;
height: 256px;
}Feels like a weird word choice to me, when 'map' was right there, but who are we to judge.
View the map a single tile at a time, no dragging the map, no moving by less than a tile, no zooming with the mousewheel, every move and zoom a full pageload.
(You'll also notice the older maps are much higher contrast than Google Maps - the older maps being modelled on printed paper maps)
There’s another challenge: you need to provide more and more data as you zoom in, wonder how that should work with vector stuff.
SVG is convenient but isn't necessary.
For example maplibre is a great option for rendering vector based openstreet maps from e.g. maptiler or mapbox. They can tilt the maps, render buildings in 3D, have step less zooming, etc.
1a25 7802 0a05 7761 7465 7228 8020 1217
1803 2213 0980 69e0 7f1a dfa8 0100 00bf
bf01 e0a8 0100 0f
Decodes to this protobuf: layers {
name: "water"
features {
type: POLYGON
geometry: 9
geometry: 13440
geometry: 16352
geometry: 26
geometry: 21599
geometry: 0
geometry: 0
geometry: 24511
geometry: 21600
geometry: 0
geometry: 15
}
extent: 4096
version: 2
}
Geometry interpretation is here: https://github.com/mapbox/vector-tile-spec/tree/master/2.1#4...And produces this geometry before reprojecting to the tile coordinates:
Layer name: water
Geometry: Polygon
Feature Count: 1
Extent: (0.000000, 0.000000) - (4096.000000, 4096.000000)
Layer SRS WKT:
(unknown)
mvt_id: Integer64 (0.0)
OGRFeature(water):0
POLYGON ((0 0,0 4096,4096 4096,4096 0,0 0))
But of course, this doesn't specify a color, just "the ocean is a rectangle".Android application OsmAnd is notoriously slow because of this: https://github.com/osmandapp/OsmAnd/discussions/11961
Assuming this level of optimization is actually warranted
This would be a 'rectangle color' specific. Probably 24 bytes to represent height, width, color? It seems like a Herculean effort to attempt to get browser support for such a thing, for a phenomenally rare use case. It would need to be an image format probably and not a browser implementation, since they're usually arranged around other images. And all for saving some 60 bytes per square.
To be clear I'm not saying it's a bad idea - I'm all for it. It just seems like a pretty edge use case(large blobs of single color images such as oceans in cartoon maps).
Worth it? Not sure. But possible? Definitely.
OSM needs 54TB for all tiles but only around 1.8% are viewed. So you need at least 1TB of cache.
I am curious if this micro optimalization really makes a difference.
I'm actually surprised they even use DOM nodes for this. Last I checked Google Maps uses a totally custom WebGL based renderer (since it supports 3D and such).
It's extra handling in the client, request and traffic is still there. Saving few bytes for extra complexity is probably not worth it.
"oxipng" (my current preferred png optimizer) bring a plain 256x256 image created with imagemagick down to 179 bytes, as long as you tell it to strip all metadata objects.
Interlacing doesn't make any difference, it's the same size with it on or off.
For OpenStreetMap 136 bytes
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256"><path d="M0 0h256v256H0z" fill="#aad3df"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 1 1"><circle r="2" fill="#aad3df"/></svg>Also - pardon my ignorance, this may be a dumb question, is SVG universally supported in browsers these days? I’m not big up on image standards.
* If you know Android Go (not Android Auto), the Maps there are raster due to hardware constraints.
<svg width="256" height="256"><rect width="100%" height="100%" fill="#aad3df" /></svg>
The image is only 22 bytes as a jxl:
https://cdn.discordapp.com/attachments/286612533757083648/96...
base64 data uri version:
data:image/jxl;base64,/wp/QCQIBgEALABLOEmIDIPCakgSBg==So instead of optimizing the size of your file directly, you could optimize the size of what's actually send over the connection.
I wonder if that would give you a slightly different png or bmp or so?
[1] https://files.littlebird.com.au/Shared-Image-2022-04-22-17-5...