picture.html
HTML document, ASCII text
1
{% extends "default.html" %}
2
{% block title %}Picture {{ resource.title }} | gigadata{% endblock %}
3
{% macro shape_label(x, y, text) %}
4
{% if text %}
5
<a class="shape-label" style="left: {{ x * 100 }}%; top: {{ y * 100 }}%" href="/object/{{ text }}">
6
{{ text }}
7
</a>
8
{% endif %}
9
{% endmacro %}
10
{% block content %}
11
<x-frame style="--width: 768px">
12
<h1>{{ resource.title }}</h1>
13
<p>by <a href="/profile/{{ resource.author.username }}">{{ resource.author.formatted_name }}</a></p>
14
<p>{{ resource.description }}</p>
15
{% if resource.replaced_by %}
16
<h2>Obsolete</h2>
17
<p>
18
This picture has been replaced by <a href="/picture/{{ resource.replaced_by.id }}">{{ resource.replaced_by.title }}</a>.
19
</p>
20
{% if have_permission %}
21
<form method="POST" action="/picture/{{ resource.id }}/remove-replacement">
22
<button class="button-flat" type="submit">Remove replacement</button>
23
</form>
24
{% endif %}
25
{% endif %}
26
<p>
27
<a href="{{ resource.origin_url }}">Original source</a> |
28
<a href="/raw/picture/{{ resource.id }}">View</a> |
29
<a href="/picture/{{ resource.id }}/get-annotations">Download annotations</a> |
30
<a href="/raw/picture/{{ resource.id }}" download="GigadataPicture_{{ resource.id }}{{ file_extension }}">Download</a> {% if have_permission %}|
31
<a href="/picture/{{ resource.id }}/annotate">Annotate</a> |
32
<a href="/picture/{{ resource.id }}/put-annotations-form">Submit JSON annotations</a> |
33
<a href="/picture/{{ resource.id }}/edit-metadata">Edit title or description</a>{% endif %} {% if current_user %}|
34
<a href="/picture/{{ resource.id }}/copy">Copy</a>{% endif %}
35
</p>
36
{% if have_permission %}
37
<details>
38
<summary>Delete</summary>
39
<a href="/picture/{{ resource.id }}/delete">Delete</a>
40
</details>
41
{% endif %}
42
<div id="annotation-zone">
43
<img id="annotation-image" src="/raw/picture/{{ resource.id }}" alt="{{ resource.title }}">
44
{% for region in resource.regions %}
45
{% if region.json.type == "bbox" %}
46
<svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}">
47
<rect x="{{ region.json.shape.x * size[0] }}"
48
y="{{ region.json.shape.y * size[1] }}"
49
width="{{ region.json.shape.w * size[0] }}"
50
height="{{ region.json.shape.h * size[1] }}"
51
fill="none" class="shape-bbox shape"
52
></rect>
53
{% set centre_x = region.json.shape.x + region.json.shape.w / 2 %}
54
{% set centre_y = region.json.shape.y + region.json.shape.h / 2 %}
55
</svg>
56
{% elif region.json.type == "polygon" %}
57
<svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}">
58
<polygon points="{% for point in region.json.shape %}{{ point.x * size[0] }},{{ point.y * size[1] }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon>
59
{% set top = region.json.shape | sort(attribute='y') | last %}
60
{% set left = region.json.shape | sort(attribute='x') | first %}
61
{% set bottom = region.json.shape | sort(attribute='y') | first %}
62
{% set right = region.json.shape | sort(attribute='x') | last %}
63
{% set centre_x = (left.x + right.x) / 2 %}
64
{% set centre_y = (top.y + bottom.y) / 2 %}
65
</svg>
66
{% elif region.json.type == "polyline" %}
67
<svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}">
68
<polyline points="{% for point in region.json.shape %}{{ point.x * size[0] }},{{ point.y * size[1] }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline>
69
{# Median point #}
70
{% set centre_x = region.json.shape | map(attribute="x") | median %}
71
{% set centre_y = region.json.shape | map(attribute="y") | median %}
72
</svg>
73
{% elif region.json.type == "point" %}
74
<svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}">
75
<circle cx="{{ region.json.shape.x * size[0] }}" cy="{{ region.json.shape.y * size[1] }}" r="0" fill="none" class="shape-point shape"></circle>
76
</svg>
77
{% endif %}
78
{{ shape_label(centre_x, centre_y, region.object_id) }}
79
{% endfor %}
80
</div>
81
<x-buttonbox>
82
<label>
83
<input type="checkbox" id="show-shapes" checked>
84
Show shapes
85
</label>
86
<label>
87
<input type="checkbox" id="show-objects" checked>
88
Show objects
89
</label>
90
</x-buttonbox>
91
{% set licences = resource.licences | map(attribute="licence") | list %}
92
{% set contains = resource.regions | map(attribute="object_id") | set | select | sort | list %}
93
<x-vbox>
94
<div class="icon-explainer">
95
<span>Type</span>
96
<span>{{ resource.nature.id }}</span>
97
<span>File format</span>
98
<span>{{ resource.file_format }}</span>
99
<span>Size</span>
100
<span>{{ size[0] }}×{{ size[1] }}</span>
101
<span>Number of regions</span>
102
<span>{{ resource.regions | length }}</span>
103
<span>Number of labelled regions</span>
104
<span>{{ resource.regions | selectattr("object_id") | list | length }}</span>
105
<span>Date uploaded</span>
106
<span>{{ resource.timestamp }}</span>
107
</div>
108
Contains objects: {{ contains | join(", ") }}
109
<x-hbox style="justify-content: space-between">
110
<small class="picture-licensing-info">
111
Available under:
112
{% for licence in licences %}
113
<a href="{{ licence.info_url }}" target="_blank">
114
{{ licence.title }}
115
</a>
116
{% if not loop.last %}, {% endif %}
117
{% endfor %}
118
</small>
119
<x-vbox class="picture-licence-logos">
120
{% for licence in licences %}
121
{% if licence.logo_url %}
122
{% if licence.info_url %}
123
<a href="{{ licence.info_url }}" target="_blank" tabindex="-1">
124
{# An equivalent link already exists, only one is focusable #}
125
<img src="{{ licence.logo_url }}" alt="{{ licence.title }}" class="licence-logo">
126
</a>
127
{% else %}
128
<img src="{{ licence.logo_url }}" alt="{{ licence.title }}" class="licence-logo">
129
{% endif %}
130
{% endif %}
131
{% endfor %}
132
</x-vbox>
133
</x-hbox>
134
<h2>Copies</h2>
135
<ul class="thumbnail-list">
136
{% for copy in resource.copies %}
137
<li>
138
<a href="/picture/{{ copy.id }}">
139
<div class="annotation-zone">
140
<img src="/raw/picture/{{ copy.id }}" alt="{{ copy.title }}">
141
142
{% for region in copy.regions %}
143
{% if region.json.type == "bbox" %}
144
<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}">
145
<rect x="{{ region.json.shape.x * copy.width }}"
146
y="{{ region.json.shape.y * copy.height }}"
147
width="{{ region.json.shape.w * copy.width }}"
148
height="{{ region.json.shape.h * copy.height }}"
149
fill="none" class="shape-bbox shape"
150
></rect>
151
</svg>
152
{% elif region.json.type == "polygon" %}
153
<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}">
154
<polygon points="{% for point in region.json.shape %}{{ point.x * copy.width }},{{ point.y * copy.height }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon>
155
</svg>
156
{% elif region.json.type == "polyline" %}
157
<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}">
158
<polyline points="{% for point in region.json.shape %}{{ point.x * copy.width }},{{ point.y * copy.height }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline>
159
</svg>
160
{% elif region.json.type == "point" %}
161
<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}">
162
<circle cx="{{ region.json.shape.x * copy.width }}" cy="{{ region.json.shape.y * copy.height }}" r="0" fill="none" class="shape-point shape"></circle>
163
</svg>
164
{% endif %}
165
{% endfor %}
166
</div>
167
<div class="list-detail">
168
{{ copy.title }}
169
</div>
170
</a>
171
<div class="list-more">
172
<form method="POST" action="/picture/{{ copy.id }}/mark-replacement">
173
<button type="submit">Designate replacement</button>
174
</form>
175
</div>
176
</li>
177
{% endfor %}
178
</x-vbox>
179
</x-frame>
180
{% endblock %}