Browse Source

Add basic map data collection and rendering.

master
Ben Kurtovic 4 years ago
parent
commit
47731c761e
6 changed files with 117 additions and 5 deletions
  1. +28
    -1
      calefaction/eve/universe.py
  2. +21
    -1
      calefaction/modules/map.py
  3. +6
    -1
      scripts/import_sde.py
  4. +3
    -0
      static/map.css
  5. +47
    -0
      static/map.js
  6. +12
    -2
      templates/map/map.mako

+ 28
- 1
calefaction/eve/universe.py View File

@@ -45,6 +45,11 @@ class _SolarSystem(_UniqueObject):
return self._data["security"]

@property
def coords(self):
"""The solar system's coordinates, as a 3-tuple of floats (x, y, z)."""
return tuple(self._data["coords"])

@property
def faction(self):
"""The solar system's faction, as a _Faction object, or None."""
if "faction" in self._data:
@@ -66,6 +71,11 @@ class _SolarSystem(_UniqueObject):
"""Whether the solar system is in nullsec."""
return self.security >= 0.45

@property
def is_whspace(self):
"""Whether the solar system is in wormhole space."""
return self.region.is_whspace


class _Constellation(_UniqueObject):
"""Represents a constellation."""
@@ -87,6 +97,11 @@ class _Constellation(_UniqueObject):
return self._universe.faction(self._data["faction"])
return self.region.faction

@property
def is_whspace(self):
"""Whether the constellation is in wormhole space."""
return self.region.is_whspace


class _Region(_UniqueObject):
"""Represents a region."""
@@ -103,6 +118,11 @@ class _Region(_UniqueObject):
return self._universe.faction(self._data["faction"])
return None

@property
def is_whspace(self):
"""Whether the region is in wormhole space."""
return self._id >= 11000000


class _Faction(_UniqueObject):
"""Represents a faction."""
@@ -173,7 +193,8 @@ class _DummySolarSystem(_SolarSystem):
"name": "Unknown",
"constellation": -1,
"region": -1,
"security": 0.0
"security": 0.0,
"coords": (0, 0, 0)
})


@@ -288,6 +309,12 @@ class Universe:
return _DummySolarSystem(self)
return _SolarSystem(self, sid, self._systems[sid])

def systems(self):
"""Return an iterator over all _SolarSystems."""
self._load()
for sid in self._systems:
yield self.system(sid)

def constellation(self, cid):
"""Return a _Constellation with the given ID.



+ 21
- 1
calefaction/modules/map.py View File

@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-

from flask import g, json
from flask_mako import render_template

from ._provided import blueprint
from ._provided import app, blueprint

def home():
"""Render and return the main map page."""
@@ -16,3 +17,22 @@ def navitem():
def map():
"""Render and return the main map page."""
return home()

@blueprint.rroute("/map/data.json")
def mapdata():
"""Render and return the map data as a JSON object."""
payload = {
"galaxy": {
system.id: {
"name": system.name,
"coords": system.coords,
"security": system.security
}
for system in g.eve.universe.systems() if not system.is_whspace
}
}
resp = app.response_class(response=json.dumps(payload), status=200,
mimetype="application/json")
resp.cache_control.private = True
resp.cache_control.max_age = 24 * 60 * 60
return resp

+ 6
- 1
scripts/import_sde.py View File

@@ -150,7 +150,9 @@ def _build_galaxy_skeleton(ids, names):
assert isinstance(sid, int)
d[sid] = {
"name": names[sid],
"constellation": -1, "region": -1, "security": 0.0
"constellation": -1,
"region": -1,
"security": 0.0
}

print("done.")
@@ -160,15 +162,18 @@ def _load_assoc_for_system(galaxy, system, rid, cid):
data = _load_yaml(system / "solarsystem.staticdata")
sid = data["solarSystemID"]
sec = data["security"]
coords = data["center"]

assert isinstance(sid, int)
assert isinstance(sec, float)
assert sid >= 0
assert sec >= -1.0 and sec <= 1.0
assert len(coords) == 3 and all(isinstance(val, float) for val in coords)

galaxy["systems"][sid]["constellation"] = cid
galaxy["systems"][sid]["region"] = rid
galaxy["systems"][sid]["security"] = sec
galaxy["systems"][sid]["coords"] = coords

if "factionID" in data:
facid = data["factionID"]


+ 3
- 0
static/map.css View File

@@ -0,0 +1,3 @@
#map .system {
fill: currentColor;
}

+ 47
- 0
static/map.js View File

@@ -0,0 +1,47 @@
$(function() {
$("#map").html("<p>Loading map data...</p>");
$.getJSON( "map/data.json", function(data) {
$("#map").empty();
var svg = d3.select("#map").append("svg")
.attr("width", 1000)
.attr("height", 1000); // TODO: dynamic

var xmin = Infinity, xmax = -Infinity,
ymin = Infinity, ymax = -Infinity;
for (var sid in data["galaxy"]) {
var system = data["galaxy"][sid];
var x = system["coords"][0];
var y = system["coords"][2];
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
}

var width = xmax - xmin;
var height = ymax - ymin;
var scale = 1000;

svg.attr("viewBox", "0 0 " + scale + " " + scale);

svg.selectAll("circle")
.data(Object.values(data["galaxy"]))
.enter()
.append("circle")
.attr("cx", (d) => {
var x = d["coords"][0];
return (x - xmin) / width * scale;
})
.attr("cy", (d) => {
var y = d["coords"][2];
return (y - ymin) / height * scale;
})
.attr("r", 1)
.attr("class", (d) => {
var sec = d["security"];
var klass = sec < 0.05 ? "null" :
Number(sec).toFixed(1).replace(".", "_");
return "system sec-" + klass;
});
});
});

+ 12
- 2
templates/map/map.mako View File

@@ -2,6 +2,16 @@
<%block name="title">
${self.support.maketitle("Map")}
</%block>
<%block name="extracss">
${self.support.makecss("map.css")}
</%block>
<%block name="extrajs">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.4.1/d3.min.js" integrity="sha256-4mL8TQfOJSbg0f42dQw5cKLl2ngQXUSXqfQnvK11M44=" crossorigin="anonymous"></script>
${self.support.makejs("map.js")}
</%block>
<h2>Map</h2>
## TODO
<p>No map available yet!</p>
<div id="map">
<noscript>
<p>JavaScript is required to display the galaxy map.</p>
</noscript>
</div>

Loading…
Cancel
Save