{"id":19795554,"url":"https://github.com/dkogan/horizonator","last_synced_at":"2025-05-01T03:30:28.066Z","repository":{"id":8931513,"uuid":"10662514","full_name":"dkogan/horizonator","owner":"dkogan","description":"Terrain renderer based on SRTM DEMs","archived":false,"fork":false,"pushed_at":"2024-10-30T18:28:31.000Z","size":5214,"stargazers_count":27,"open_issues_count":1,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-06T08:07:52.194Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dkogan.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-06-13T09:02:52.000Z","updated_at":"2024-10-30T18:28:35.000Z","dependencies_parsed_at":"2023-12-29T19:30:32.463Z","dependency_job_id":"8c3b685a-c8f1-48ed-9084-e8ff74dc8d60","html_url":"https://github.com/dkogan/horizonator","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkogan%2Fhorizonator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkogan%2Fhorizonator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkogan%2Fhorizonator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkogan%2Fhorizonator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dkogan","download_url":"https://codeload.github.com/dkogan/horizonator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251817808,"owners_count":21648811,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T07:16:38.863Z","updated_at":"2025-05-01T03:30:27.728Z","avatar_url":"https://github.com/dkogan.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"#+TITLE: Horizonator!\n\n* Overview\nThis tool renders terrain data, and can be used to simulate views captured by\na camera. This is most useful in areas with significant topographic relief.\n\nThere are a number of other, more polished tools to do this\n\n- http://www.udeuschle.selfhost.pro/panoramas/makepanoramas_en.htm\n- https://www.peakfinder.org/\n- https://www.caltopo.com (right click, \"point info\", \"view from here\")\n\nAlthough less polished, the implementation in the horizonator is freely licensed\n(under any version of the LGPL), and is a good base for experimentation. The\nhorizonator is mostly intended as a building block for other tools, so the\nuser-facing UI tool is somewhat feature-sparse.\n\nThe horizonator consists of a [[https://github.com/dkogan/horizonator/blob/master/horizonator.h][C library]], a [[https://github.com/dkogan/horizonator/blob/master/horizonator.docstring][Python library]] and two user-facing\ntools:\n\n- The =horizonator= tool: an interactive [[https://www.fltk.org/][FLTK]] application that displays an\n  overhead map and a render, allowing the user to interactively move around in\n  both those views, and to relate the views to each other\n\n- The =standalone= tool: a one-render application. Can produce either a static\n  GLUT window or a =.png= image on disk\n\n* Building the horizonator\nThis isn't \"released\", so I'm not providing packages, and building from source\nis required. This probably can work on any recent UNIXy platform, but I've only\ntested on Debian and CentOS.\n\nOn Debian, you need the following packages (I believe that's it; may be missing\none or two):\n\n- libfltk1.3-dev\n- libboost-filesystem-dev\n- libboost-system-dev\n- libboost-thread-dev\n- libcurl4-gnutls-dev\n- libgl1-mesa-dev\n- libepoxy-dev\n- libglu-dev\n- libpng12-dev\n- libfreeimage-dev\n- libtinyxml-dev\n- libpython3-dev\n\nOnce you have those, run =make=. You also need =wget= at runtime to download\nthe tiles.\n\n* Using the horizonator \nBefore running the tool, you need data to render. By default the horizonator\nuses 3sec [[https://en.wikipedia.org/wiki/Shuttle_Radar_Topography_Mission][SRTM]] DEMs. Raw SRTM data contains gaps, so I usually use the\ngap-filled SRTM data from\n\n  http://viewfinderpanoramas.org/dem3.html\n\nYou need to download the archive for your area (for North America, you can [[http://viewfinderpanoramas.org/Coverage%20map%20viewfinderpanoramas_org3.htm][pick\nfrom a map]]). Then extract the =.hgt= files to\n\n  =~/.horizonator/DEMs_SRTM3=\n\nAny missing DEM files are assumed to describe an area at elevation = 0 (such as\nan area of open ocean). After the DEMs are downloaded, the tool can be run\n(OpenStreetMap tiles are required too, but those are downloaded automatically at\nruntime).\n\nThere's an interactive tool for humans to mess around with, and a standalone\ntool to just make single renders (useful for scripting)\n\n** Interactive\nThe interactive tool is invoked by running the =./horizonator= executable.\n=./horizonator --help= has basic usage instructions. The only required arguments\nare the latitude and longitude of the viewer. Example: standing on top of Iron\nMt, looking N and E towards Mount Baden-Powell and Baldy:\n\n#+begin_example\n./horizonator --zfar-color 8000 34.2884 -117.7134 45 80\n#+end_example\n\n[[file:example-interactive.png]]\n\nThis brings up a window where the top half shows an OpenStreetMap slippy map.\nOSM tiles are downloaded (and cached locally to =~/.horizonator/tiles/=) as\nrequired. The extents of the current view are shown as lines in the render. The\ncurrently-loaded data is also shown, as a rectangle. The data is loaded at the\nbeginning, centered on the latitude,longitude given on the commandline. To load\na different set of data, re-launch the application.\n\nThe bottom half shows the render. By default, the shade of red encodes the\ndistance to the viewer. It is possible instead to texture the render using the\nmap; pass =--texture= to select this mode. Currently this uses the same\nOpenStreetMap tiles that are used in the slippy-map, which isn't terribly\nuseful. Eventually topography or aerial imagery should be hooked in here.\n\nThe initial render is made from the latitude,longitude position given on the\ncommandline (the altitude is sampled from the DEM). The user may change the\nviewpoint at runtime, but new data is loaded /only/ at the start.\n\n*** UI\n- Mousewheel up/down in the slippy map: zoom in/out\n- Left click/drag in the slippy map: pan\n- Right click in the slippy map: re-render the currently-loaded data from that\n  location\n- Mousewheel up/down in the render: zoom in/out. Changes the azimuth extents.\n  Does /not/ change the pitch or roll or yaw. The viewer always look out\n  parallel to the ground plane: pitch, roll are always 0.\n- Mousewheel left/right in the render: pan left/right. Changes the yaw only.\n- Left click/drag in the render: pan by moving the azimuth extents and/or the\n  yaw. Exactly what the mousewheel does.\n- Right click in the render: display the rendered point on the slippy map.\n  Useful for identifying peaks.\n- Keyboard =w=: cycle between filled triangles, wireframe and point renders\n- Keyboard =r=: cycle between the two winding directions; this is only useful\n  for debugging.\n- Keyboard =q=: quit\n\n** Commandline\nIf all we want is a single render from a known position, with known azimuth\nbounds, run the =./standalone= tool. Example:\n\n#+begin_example\n./standalone --width 800 --image example-standalone.png  --zfar-color 8000 34.2884 -117.7134 -35 125\n#+end_example\n\n[[file:example-standalone.png]]\n\nThis can either run a static GLUT application, or it can render to a =.png=\nimage on disk and/or a binary range image. Run with =--help= for details. Note\nthat the azimuth extents are currently specified differently than they are in\nthe interactive tool.\n\n** C API\nThe tool can be invoked from C. The [[https://github.com/dkogan/horizonator/blob/master/horizonator.h][header comments]] and its usages in the\ncommandline tool should be clear.\n\n** Python API\nA Python interface is provided, and is built as part of the normal invocation of\n=make=. The Python library consists of\n\n- [[https://github.com/dkogan/horizonator/blob/master/horizonator.docstring][a =horizonator= object constructor]]\n- [[https://github.com/dkogan/horizonator/blob/master/render.docstring][a =render= function]]\n\nThis works similarly to the other components: the constructor loads the data,\nand we can then render it in different ways by calling =render()= repeatedly.\n\n* Render details\nThe tool uses an equirectangular projection. The x coordinate of the rendered\nimage represents the azimuth: the viewing direction. The y coordinate represents\nthe elevation: the angle above/below the horizontal. The same angular resolution\nis used in both directions. As elevation increases, this projection acquires\nmore and more distortion, but with small elevation angles (the usual case)\nthings works well.\n\nThe view straight ahead (elevation = 0) is at the center of the render.\n\nThis tool operates in the tangent plane to the viewer, so it assumes that\nlocally, the Earth is flat. This produces small inaccuracies, but unless we care\nabout small pixel-level errors, this is a good approximation. I will eventually\nfix this.\n\n* DEM resolution\nBy default, 3\" DEMs are used. These are the low-res SRTM data, which is\ngenerally plenty hi-res-enough for this application. For more faithful rendering\nof very near objects, the resolution can become a problem, so the\nhigher-resolution 1\" DEMS may be used. These are better, but they exacerbate an\nimplementation detail in the horizonator, so the 3\" DEMs are used by default.\nCurrently every triangle in the mesh is rendered, even those that are very far\naway, and look tiny. A coarser mesh would be more appropriate for far-off\nobjects. Until that is implemented, the 9x increase in triangles present in the\nSRTM1 data could become a problem. Support for 1\" data /is/ in place, and can be\nselected with the =SRTM1= option in all the APIs and commandline tools.\n\n* Nice-to-have improvements\nIn no particular order:\n\n- Texturing with aerial imagery\n- Being more efficient about data loading: the DEM and texture resolution needs\n  to be high close-in, but can be dramatically lower further out.\n- Higher-res DEMs are available (1sec SRTM instead of 3sec). It would be nice to\n  use them, /if/ we can do so efficiently\n- Nicer handling of the mesh immediately near the viewer.\n- Intelligently loading faraway data. Currently we load data a constant number\n  of cells away from the viewer\n- Peak-labelling the render\n- More UI stuff\n  - text showing the current lat, lon, az bounds\n  - text inputs to change the current lat, lon, az bounds\n  - controls to re-center the data, to get more data in some particular\n    direction\n  - controls to change the texturing, shading configuration, etc\n  - controls to save renders to disk\n- Auto-downloading DEMs\n\n* License and copyright\n** Horizonator (everything except =florb/=)\nCopyright 2012-2021 Dima Kogan \u003cdima@secretsauce.net\u003e\nReleased under the terms of the GNU LGPL (any version)\n\n** =florb/=\nCopyright (c) 2010, Björn Rehm (bjoern@shugaa.de)\nReleased under the terms of the MIT license\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkogan%2Fhorizonator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdkogan%2Fhorizonator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkogan%2Fhorizonator/lists"}