prospect and moving code to better places

This commit is contained in:
Philip Sargent 2021-04-17 01:41:06 +01:00
parent 4ad7033285
commit f8b613e0aa
6 changed files with 129 additions and 87 deletions

View File

@ -24,7 +24,7 @@ import troggle.core.models.survex
from troggle.core.utils import get_process_memory from troggle.core.utils import get_process_memory
"""This file declares TroggleModel which inherits from django.db.models.Model """This file declares TroggleModel which inherits from django.db.models.Model
All TroggleModel subclasses inherit persistence in the django relational database. This is known as All TroggleModel and models.Model subclasses inherit persistence in the django relational database. This is known as
the django Object Relational Mapping (ORM). the django Object Relational Mapping (ORM).
There are more subclasses define in models_caves.py models_survex.py etc. There are more subclasses define in models_caves.py models_survex.py etc.
""" """

View File

@ -354,7 +354,7 @@ def edit_cave(request, slug=None):
}) })
@login_required_if_public @login_required_if_public
def editEntrance(request, caveslug, slug=None): def edit_entrance(request, caveslug=None, slug=None):
'''This is the form that edits the entrance data for a single entrance and writes out '''This is the form that edits the entrance data for a single entrance and writes out
an XML file in the :expoweb: repo folder an XML file in the :expoweb: repo folder
The format for the file being saved is in templates/dataformat/entrance.xml The format for the file being saved is in templates/dataformat/entrance.xml
@ -362,7 +362,10 @@ def editEntrance(request, caveslug, slug=None):
It does save the data into into the database directly, not by parsing the file. It does save the data into into the database directly, not by parsing the file.
''' '''
message = "" message = ""
cave = Cave.objects.get(caveslug__slug = caveslug) if caveslug is not None:
cave = Cave.objects.get(caveslug__slug = caveslug)
else:
cave = Cave()
if slug is not None: if slug is not None:
entrance = Entrance.objects.get(entranceslug__slug = slug) entrance = Entrance.objects.get(entranceslug__slug = slug)
else: else:

View File

@ -13,6 +13,7 @@ from django.shortcuts import render
import troggle.settings as settings import troggle.settings as settings
from troggle.core.models.caves import Entrance, Area, SurvexStation, Cave from troggle.core.models.caves import Entrance, Area, SurvexStation, Cave
from troggle.core.views.caves import caveKey from troggle.core.views.caves import caveKey
from troggle.parsers.survex import MapLocations
''' Generates the prospecting guide document. ''' Generates the prospecting guide document.
@ -61,49 +62,7 @@ def prospecting(request):
areas.append((name, a, caves)) areas.append((name, a, caves))
return render(request, 'prospecting.html', {"areas": areas}) return render(request, 'prospecting.html', {"areas": areas})
class MapLocations(object):
p = [
("laser.0_7", "BNase", "Reference", "Bräuning Nase laser point"),
("226-96", "BZkn", "Reference", "Bräuning Zinken trig point"),
("vd1","VD1","Reference", "VD1 survey point"),
("laser.kt114_96","HSK","Reference", "Hinterer Schwarzmooskogel trig point"),
("2000","Nipple","Reference", "Nipple (Weiße Warze)"),
("3000","VSK","Reference", "Vorderer Schwarzmooskogel summit"),
("topcamp", "OTC", "Reference", "Old Top Camp"),
("laser.0", "LSR0", "Reference", "Laser Point 0"),
("laser.0_1", "LSR1", "Reference", "Laser Point 0/1"),
("laser.0_3", "LSR3", "Reference", "Laser Point 0/3"),
("laser.0_5", "LSR5", "Reference", "Laser Point 0/5"),
("225-96", "BAlm", "Reference", "Bräuning Alm trig point")
]
def points(self):
for ent in Entrance.objects.all():
if ent.best_station():
try:
k = ent.caveandentrance_set.all()[0].cave
except:
message = " ! Failed to get Cave linked to Entrance:{} from:{} best:{}".format(ent.name, ent.filename, ent.best_station())
DataIssue.objects.create(parser='entrances', message=message)
print(message)
raise
try:
areaName = k.getArea().short_name
except:
message = " ! Failed to get Area on cave '{}' linked to Entrance:{} from:{} best:{}".format(cave, ent.name, ent.filename, ent.best_station())
DataIssue.objects.create(parser='entrances', message=message)
print(message)
raise
self.p.append((ent.best_station(), "%s-%s" % (areaName, str(ent)[5:]), ent.needs_surface_work(), str(ent)))
return self.p
def __str__(self):
return "{} map locations".format(len(self.p))
# Parameters for big map and zoomed subarea maps: # Parameters for big map and zoomed subarea maps:
# big map first (zoom factor ignored) # big map first (zoom factor ignored)
@ -143,6 +102,7 @@ R = 2
B = 3 B = 3
ZOOM = 4 ZOOM = 4
DESC = 5 DESC = 5
SIZE = 5
areacolours = { areacolours = {
'1a' : '#00ffff', '1a' : '#00ffff',
@ -170,7 +130,7 @@ TEXTSIZE = 16
CIRCLESIZE =8 CIRCLESIZE =8
LINEWIDTH = 2 LINEWIDTH = 2
myFont = ImageFont.truetype(FONT, TEXTSIZE) myFont = ImageFont.truetype(FONT, TEXTSIZE)
print(f' - myFont {myFont} {FONT} {TEXTSIZE}') #print(f' - myFont {myFont} {FONT} {TEXTSIZE}')
def mungecoord(x, y, mapcode, img): def mungecoord(x, y, mapcode, img):
# Top of Zinken is 73 1201 = dataset 34542 81967 # Top of Zinken is 73 1201 = dataset 34542 81967
@ -194,41 +154,24 @@ COL_TYPES = {True: "red",
False: "#dddddd", False: "#dddddd",
"Reference": "#dddddd"} "Reference": "#dddddd"}
def plot(surveypoint, number, point_type, label, mapcode, draw, img):
try:
ss = SurvexStation.objects.lookup(surveypoint)
E, N = ss.x, ss.y
shortnumber = number.replace("—","")
(x,y) = list(map(int, mungecoord(E, N, mapcode, img)))
imgmaps[maparea].append( [x-4, y-SIZE/2, x+4+draw.textsize(shortnumber)[0], y+SIZE/2, shortnumber, label] )
draw.rectangle([(x+CIRCLESIZE, y-TEXTSIZE/2), (x+CIRCLESIZE*2+draw.textsize(shortnumber)[0], y+TEXTSIZE/2)], fill="#ffffff")
draw.text((x+CIRCLESIZE * 1.5,y-TEXTSIZE/2), shortnumber, fill="#000000")
draw.ellipse([(x-CIRCLESIZE,y-CIRCLESIZE),(x+CIRCLESIZE,y+CIRCLESIZE)], fill=COL_TYPES[point_type], outline="#000000")
except:
pass
def prospecting_image(request, name): def prospecting_image(request, name):
# We should replace all this with something that exports an overlay for Google Maps and OpenStreetView '''This draws map outlines on an existing map image.
But getting the entrances plotted is broken by later changes elsewhere in the system since this code was written.
# test = os.path.join(settings.EXPOFILES, "location_maps", "testmap.png") SurvexStations are in x=latitude, y=longitude - these are what appear in essentials.gpx
# response = HttpResponse(content_type = "image/png") Entrances are in northing, easting
# with Image.open(test) as im:
# draw = ImageDraw.Draw(im)
# draw.line((0, 0) + im.size, fill=128)
# draw.line((0, im.size[1], im.size[0], 0), fill=128)
# # write to stdout
# #im.save(sys.stdout, "PNG")
# img.save(response, "PNG")
# return response which is why we can't simply plot all the Entrances...
We should replace all this with something that exports an overlay for Google Maps and OpenStreetView
'''
mainImage = Image.open(os.path.join(settings.EXPOFILES, "location_maps", "pguidemap.jpg")) mainImage = Image.open(os.path.join(settings.EXPOFILES, "location_maps", "pguidemap.jpg"))
# if settings.PUBLIC_SITE and not request.user.is_authenticated: # if settings.PUBLIC_SITE and not request.user.is_authenticated:
# mainImage = Image.new("RGB", mainImage.size, '#ffffff') # mainImage = Image.new("RGB", mainImage.size, '#ffffff')
m = maps[name] m = maps[name]
#imgmaps = [] imgmaps = []
if name == "all": if name == "all":
img = mainImage img = mainImage
else: else:
@ -255,7 +198,7 @@ def prospecting_image(request, name):
textlen = draw.textsize(text)[0] + 3 textlen = draw.textsize(text)[0] + 3
draw.rectangle([l, t, l+textlen, t+TEXTSIZE+2], fill='#ffffff') draw.rectangle([l, t, l+textlen, t+TEXTSIZE+2], fill='#ffffff')
draw.text((l+2, t+1), text, fill="#000000", font=myFont) draw.text((l+2, t+1), text, fill="#000000", font=myFont)
#imgmaps.append( [l, t, l+textlen, t+SIZE+2, "submap" + maparea, maparea + " subarea map"] ) imgmaps.append( [l, t, l+textlen, t+SIZE+2, "submap" + maparea, maparea + " subarea map"] )
draw.line([l, t, r, t], fill='#777777', width=LINEWIDTH) draw.line([l, t, r, t], fill='#777777', width=LINEWIDTH)
draw.line([l, b, r, b], fill='#777777', width=LINEWIDTH) draw.line([l, b, r, b], fill='#777777', width=LINEWIDTH)
draw.line([l, t, l, b], fill='#777777', width=LINEWIDTH) draw.line([l, t, l, b], fill='#777777', width=LINEWIDTH)
@ -265,6 +208,7 @@ def prospecting_image(request, name):
draw.line([l, t, l, t+TEXTSIZE+2], fill='#777777', width=LINEWIDTH) draw.line([l, t, l, t+TEXTSIZE+2], fill='#777777', width=LINEWIDTH)
draw.line([l+textlen, t, l+textlen, t+TEXTSIZE+2], fill='#777777', width=LINEWIDTH) draw.line([l+textlen, t, l+textlen, t+TEXTSIZE+2], fill='#777777', width=LINEWIDTH)
#imgmaps[maparea] = [] #imgmaps[maparea] = []
# Draw scale bar # Draw scale bar
m100 = int(100 / (m[R] - m[L]) * img.size[0]) m100 = int(100 / (m[R] - m[L]) * img.size[0])
draw.line([10, TEXTSIZE*3, 10, TEXTSIZE*2], fill='#000000', width=LINEWIDTH) draw.line([10, TEXTSIZE*3, 10, TEXTSIZE*2], fill='#000000', width=LINEWIDTH)
@ -273,11 +217,8 @@ def prospecting_image(request, name):
label = "100m" label = "100m"
draw.text([10 + (m100 - draw.textsize(label)[0]) / 2, TEXTSIZE/2], label, fill='#000000', font=myFont) draw.text([10 + (m100 - draw.textsize(label)[0]) / 2, TEXTSIZE/2], label, fill='#000000', font=myFont)
ml = MapLocations() # Draw the circles for known points
for p in ml.points(): # Northing, Easting, Diameter - but N&E are swapped re database
surveypoint, number, point_type, label = p
plot(surveypoint, number, point_type, label, name, draw, img)
for (N, E, D, num) in [(35975.37, 83018.21, 100, "177"), # Calculated from bearings for (N, E, D, num) in [(35975.37, 83018.21, 100, "177"), # Calculated from bearings
(35350.00, 81630.00, 50, "71"), # From Auer map (35350.00, 81630.00, 50, "71"), # From Auer map
(36025.00, 82475.00, 50, "146"), # From mystery map (36025.00, 82475.00, 50, "146"), # From mystery map
@ -297,8 +238,66 @@ def prospecting_image(request, name):
draw.ellipse([lo[0]+2, lo[1]+2, hi[0]-2, hi[1]-2], outline=areacolours[maparea]) draw.ellipse([lo[0]+2, lo[1]+2, hi[0]-2, hi[1]-2], outline=areacolours[maparea])
draw.rectangle([lpos[0],lpos[1]-TEXTSIZE/2, lpos[0] + draw.textsize(name)[0], lpos[1]+TEXTSIZE/2], fill="#ffffff") draw.rectangle([lpos[0],lpos[1]-TEXTSIZE/2, lpos[0] + draw.textsize(name)[0], lpos[1]+TEXTSIZE/2], fill="#ffffff")
draw.text((lpos[0], lpos[1]-TEXTSIZE/2), num, fill="#000000") draw.text((lpos[0], lpos[1]-TEXTSIZE/2), num, fill="#000000")
#print(f' CIRCLES - {num} {(N,E,D)}')
# ml = MapLocations()
# for p in ml.points():
# surveypoint, number, point_type, label = p
# print(f'{surveypoint}, {number}, {point_type}, {label}')
# plot(surveypoint, number, True, label, name, draw, img)
# print(f'{name},\n{draw},\n{img}')
ents = Entrance.objects.all() # only has entrances and fixed points in it these days,
# but there are only 11 Entrances with northing, easting and a useable tag!
D = 50
for e in ents:
try:
E, N = e.easting, e.northing
if e.tag_station:
st = e.tag_station
elif e.exact_station:
st = e.exact_station
elif e.exact_station:
st = e.exact_station
else:
# print(f' No tag - {e.name} ')
continue
if not e.northing:
continue
lo = mungecoord(N-D, E+D, st, img)
hi = mungecoord(N+D, E-D, st, img)
lpos = mungecoord(N-D, E, st, img)
draw.ellipse([lo,hi], outline="#000000")
draw.ellipse([lo[0]+1, lo[1]+1, hi[0]-1, hi[1]-1], outline="#ffffff")
draw.ellipse([lo[0]+2, lo[1]+2, hi[0]-2, hi[1]-2], outline="#ffffff")
draw.rectangle([lpos[0],lpos[1]-TEXTSIZE/2, lpos[0] + draw.textsize(st)[0], lpos[1]+TEXTSIZE/2], fill="#ffffff")
draw.text((lpos[0], lpos[1]-TEXTSIZE/2), num, fill="#000000")
# draw.ellipse([(x-CIRCLESIZE,y-CIRCLESIZE),(x+CIRCLESIZE,y+CIRCLESIZE)], fill="red", outline="blue")
# draw.rectangle([(x+CIRCLESIZE, y-TEXTSIZE/2), (x+CIRCLESIZE*2+draw.textsize(shortnumber)[0], y+TEXTSIZE/2)], fill="#ffffff")
# draw.text((x+CIRCLESIZE * 1.5,y-TEXTSIZE/2), shortnumber, fill="#000000")
#print(f' SUCCESS - {st} {(E, N)} ')
except:
#print(f' FAIL - {st} {(E, N)} ')
pass
response = HttpResponse(content_type = "image/png") response = HttpResponse(content_type = "image/png")
del draw del draw
img.save(response, "PNG") img.save(response, "PNG")
return response
return response
# def plot(surveypoint, number, point_type, label, mapcode, draw, img):
# try:
# ss = SurvexStation.objects.lookup(surveypoint)
# E, N = ss.x, ss.y
# shortnumber = number.replace("—","")
# (x,y) = list(map(int, mungecoord(E, N, mapcode, img)))
# imgmaps[maparea].append( [x-4, y-SIZE/2, x+4+draw.textsize(shortnumber)[0], y+SIZE/2, shortnumber, label] )
# draw.rectangle([(x+CIRCLESIZE, y-TEXTSIZE/2), (x+CIRCLESIZE*2+draw.textsize(shortnumber)[0], y+TEXTSIZE/2)], fill="#ffffff")
# draw.text((x+CIRCLESIZE * 1.5,y-TEXTSIZE/2), shortnumber, fill="#000000")
# draw.ellipse([(x-CIRCLESIZE,y-CIRCLESIZE),(x+CIRCLESIZE,y+CIRCLESIZE)], fill=COL_TYPES[point_type], outline="#000000")
# print(f' SUCCESS - YES {surveypoint}, {number}, {point_type}, {label}')
# except:
# print(f' - NO {surveypoint}, {number}, {point_type}, {label}')
# pass

View File

@ -12,11 +12,10 @@ from django.utils.timezone import get_current_timezone
from django.utils.timezone import make_aware from django.utils.timezone import make_aware
import troggle.settings as settings import troggle.settings as settings
import troggle.core.models.caves as models_caves from troggle.core.models.caves import Entrance, QM
from troggle.core.utils import get_process_memory, chaosmonkey from troggle.core.utils import get_process_memory, chaosmonkey
from troggle.parsers.people import GetPersonExpeditionNameLookup from troggle.parsers.people import GetPersonExpeditionNameLookup
from troggle.parsers.logbooks import GetCaveLookup from troggle.parsers.logbooks import GetCaveLookup
from troggle.core.views.prospect import MapLocations
from troggle.core.models.troggle import DataIssue, Expedition from troggle.core.models.troggle import DataIssue, Expedition
from troggle.core.models.survex import SurvexPersonRole, ScansFolder, SurvexDirectory, SurvexFile, SurvexBlock, SurvexStation from troggle.core.models.survex import SurvexPersonRole, ScansFolder, SurvexDirectory, SurvexFile, SurvexBlock, SurvexStation
@ -32,6 +31,46 @@ debugprint = False # Turns on debug printout for just one *include file
debugprinttrigger = "!" debugprinttrigger = "!"
# debugprinttrigger = "caves-1623/40/old/EisSVH" # debugprinttrigger = "caves-1623/40/old/EisSVH"
class MapLocations(object):
p = [
("laser.0_7", "BNase", "Reference", "Bräuning Nase laser point"),
("226-96", "BZkn", "Reference", "Bräuning Zinken trig point"),
("vd1","VD1","Reference", "VD1 survey point"),
("laser.kt114_96","HSK","Reference", "Hinterer Schwarzmooskogel trig point"),
("2000","Nipple","Reference", "Nipple (Weiße Warze)"),
("3000","VSK","Reference", "Vorderer Schwarzmooskogel summit"),
("topcamp", "OTC", "Reference", "Old Top Camp"),
("laser.0", "LSR0", "Reference", "Laser Point 0"),
("laser.0_1", "LSR1", "Reference", "Laser Point 0/1"),
("laser.0_3", "LSR3", "Reference", "Laser Point 0/3"),
("laser.0_5", "LSR5", "Reference", "Laser Point 0/5"),
("225-96", "BAlm", "Reference", "Bräuning Alm trig point")
]
def points(self):
for ent in Entrance.objects.all():
if ent.best_station():
try:
k = ent.caveandentrance_set.all()[0].cave
except:
message = " ! Failed to get Cave linked to Entrance:{} from:{} best:{}".format(ent.name, ent.filename, ent.best_station())
DataIssue.objects.create(parser='entrances', message=message)
print(message)
raise
try:
areaName = k.getArea().short_name
except:
message = " ! Failed to get Area on cave '{}' linked to Entrance:{} from:{} best:{}".format(cave, ent.name, ent.filename, ent.best_station())
DataIssue.objects.create(parser='entrances', message=message)
print(message)
raise
self.p.append((ent.best_station(), "%s-%s" % (areaName, str(ent)[5:]), ent.needs_surface_work(), str(ent)))
message = f" - {len(self.p)} entrances linked to caves."
print(message)
return self.p
def __str__(self):
return "{} map locations".format(len(self.p))
class SurvexLeg(): class SurvexLeg():
"""No longer a models.Model subclass, so no longer a database table """No longer a models.Model subclass, so no longer a database table
""" """
@ -468,7 +507,7 @@ class LoadingSurvex():
# NB none of the SurveyStations are in the DB now, so if we want to link to aSurvexStation # NB none of the SurveyStations are in the DB now, so if we want to link to aSurvexStation
# we would have to create one. But that is not obligatory and no QMs loaded from CSVs have one # we would have to create one. But that is not obligatory and no QMs loaded from CSVs have one
try: try:
qm = models_caves.QM.objects.create(number=qm_no, qm = QM.objects.create(number=qm_no,
# nearest_station=a_survex_station_object, # can be null # nearest_station=a_survex_station_object, # can be null
nearest_station_description=qm_resolve_station, nearest_station_description=qm_resolve_station,
nearest_station_name=qm_nearest, nearest_station_name=qm_nearest,
@ -747,7 +786,7 @@ class LoadingSurvex():
path_match = re.search(r"caves-(\d\d\d\d)/(\d+|\d\d\d\d-?\w+-\d+)/", survexblock.survexfile.path) path_match = re.search(r"caves-(\d\d\d\d)/(\d+|\d\d\d\d-?\w+-\d+)/", survexblock.survexfile.path)
if path_match: if path_match:
pos_cave = '%s-%s' % (path_match.group(1), path_match.group(2)) pos_cave = '%s-%s' % (path_match.group(1), path_match.group(2))
cave = models_caves.getCaveByReference(pos_cave) cave = getCaveByReference(pos_cave)
if cave: if cave:
survexfile.cave = cave survexfile.cave = cave
@ -1369,5 +1408,5 @@ def LoadPositions():
print(message) print(message)
DataIssue.objects.create(parser='survex', message=message) DataIssue.objects.create(parser='survex', message=message)
raise raise
print(" - {} SurvexStation entrances found.".format(found)) print(" - {} SurvexStation entrances found.".format(found))

View File

@ -28,6 +28,7 @@
<p style="text-align:right"> <p style="text-align:right">
<a href="{% url "newcave" %}">New Cave</a><br> <a href="{% url "newcave" %}">New Cave</a><br>
<a href="{% url "newentrance" %}">New Entrance</a><br>
<a href="/noinfo/cave-number-index">Cave Number Index - kept updated</a> <a href="/noinfo/cave-number-index">Cave Number Index - kept updated</a>
</p> </p>
<h3>1623</h3> <h3>1623</h3>

View File

@ -120,8 +120,8 @@ trogglepatterns = [
url(r'^(?P<karea>162\d)(?P<subpath>.*)$', cavepage, name="cavepage"), # shorthand /1623/264 BUT url links may break url(r'^(?P<karea>162\d)(?P<subpath>.*)$', cavepage, name="cavepage"), # shorthand /1623/264 BUT url links may break
# Entrances # Entrances
url(r'^entrance/(?P<caveslug>[^/]+)/(?P<slug>[^/]+)/edit/', caves.editEntrance, name = "editentrance"), url(r'^entrance/new/$', caves.edit_entrance, name = "newentrance"),
url(r'^entrance/new/(?P<caveslug>[^/]+)/', caves.editEntrance, name = "newentrance"), # NOT WORKING url(r'^entrance/(?P<caveslug>[^/]+)/(?P<slug>[^/]+)/edit/', caves.edit_entrance, name = "editentrance"),
url(r'^statistics/?$', statistics.stats, name="stats"), url(r'^statistics/?$', statistics.stats, name="stats"),