User Tools

Site Tools


project:bioosm:start

This is an old revision of the document!


BioOSM

Biologicke zbrane ve vasem okoli
bioosm.jpg
founder: sachy
depends on:
interested: sumie-dh
software license: CC-BY-SA
hardware license: N/A

~~META: status = active &relation firstimage = :project:bioosm:bioosm.jpg ~~

BioOSM je mapa vyskytu mikroorganismu (ras, bakterii, plostenek, …) a do budoucna i dalsich prirodnin (mineralu, …).

K cemu to je

  • interaktivni mapa vhodna k zobrazovani vetsiho mnozstvi fotek, brmlabi wiki, sluzby typu phtagr a soup se zdaly nevhodne k publikaci tohoto typu obsahu, wiki by byla prilis obludna, na beznych sdilecich obrazkovych sluzbach se neda nic pohodlne dohledavat a davat tam biologicky smysluplne a prehledne popisky
  • monitoring zivocichu a rostlin podle zajmu prispevovatelu
  • snadne klikaci katalogovani nalezu skrze Tellico nevyzadujici coding skills
  • TODO - jednoduche selekce zajmoveho okruhu subjektu [napr. podle rodu, biotopu, datumu] na mape
  • procvicovani temne magie commandu grep, sed a regexpu

Jak to funguje

Podklad jsou OSM, ktere maji API OpenLayers jez umoznuje pridavat do mapy vlastni body, vrstvy…

Jednotliva pozorovani jsou v databazi Tellico. Udelal jsem script parse_tellico.sh, ktery z .tc databaze (je to vlastne ZIP s XML uvnitr) vyparsuje jednotlive polozky a vygeneruje HTML soubor s mapou a podadresar “det” s HTML strankami s detaily jednotlivych pozorovani. Vygeneruje se taky JSON s vyparsovanymi polozkami, ktery lze z webu projektu stahnout.

Pro nadsence je vygenerovany taky prehled prispevku plainlog.htm serazeny dle data pridani do databaze.

Pokud chcete vedet co je noveho, odebirejte projektovou RSS

Obrazky v plnem rozliseni jsou v podadresari “img”, nahledy v “simg”. Videa jsou nahrana na YT a misto nahledu maji generickou ikonu.

Pozorovani ktera se v mape zobrazi lze filtrovat dle prislusnosti k radu (bakterie, zvirata, rostliny,…) az po prislusnost k jednotlivym druhum.

Tellico sample database

Az se mi ho podari nekam nahrat tak nekde bude. Nebo mozna nejaky webxicht…

Kusy zdrojaku k nezapomenuti

Extrakce polozek z Tellico databaze

  1. ziskani tellico.xml
  2. radkovani dle polozek
  3. pouze verejne (strcit-do-mapy = yep)
  4. preneseni lokality na zacatek radku s informacemi o polozce
  5. seskupeni dle lokality
praseTC=$(unzip -p "$1" tellico.xml | tr -d '\n' | sed -e $'s/<entry id="/\\\n<entry id="/g' -e $'s/<\/entry>/<\/entry>\\\n/g' | grep -Pe '^<entry id="' | grep "<strcit-do-mapy>yep</strcit-do-mapy>" | sed -E 's/(^.*)(<locality>.*<\/locality>)(.*$)/\2\1\3/' | sort)

Prepinani vrstev

Nazvy vrstev musi byt v JS poli kvuli ovladacimu API (skryti/zobrazeni)

var laycon = [vectorLayer,ALL];
...
laycon.push(vrstva);
var controls = {
  selector: new OpenLayers.Control.SelectFeature(laycon,{onSelect: createPopup, onUnselect: destroyPopup})
};
map.addControl(controls['selector']);
controls['selector'].activate();

Prepnuti viditelnych vrstev

function kinchange() {
  kinsel=document.getElementById('kin');
  kinopt=kinsel.options[kinsel.selectedIndex].text;
  for (var i = map.layers.length - 1; i >= 1; i--) {
    map.removeLayer(map.layers[i]);
  }
  map.addLayer(window[kinopt])
}

Nastaveni brmlabu do paticky map

OpenLayers.Layer.Vector('Overlay',{attribution:'<a href="http://brmlab.cz">Brmlab</a>'});

Umisteni copyrightu

OSM maji defaultne copyright nesmyslne odsazeny od spodniho okraje mapy, CSS zmena na nejaky rozumny offset:

.olControlAttribution
{
  bottom:0.5em;
}

parse_tellico.sh

parse_tellico.sh
#!/bin/bash
# Parse Tellico database to BioOSM index.htm
# $1 = tellico .tc file
# Print result to stdout
#
# <iframe width="500" height="500" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://www.openstreetmap.org/export/embed.html?bbox=14.978000%2C49.990000%2C15.022000%2C50.010000&amp;layer=mapnik&amp;marker=50.000000%2C15.000000"></iframe>
# // vectorLayer.removeFeatures(atol)
# // map.removeLayer(vectorLayer)
#
#
# Creates:
#   (to stdout) HTML file with the map and static entries
#   ./det/ID.htm details of each and every entry
#   ./bioosm.json JSON of all entries
#   ./bioosm.rss updated RSS feed
#   ./plainlog.htm sorted entries for easy human/alg
#
 
rm -rfv "./det/*"
mkdir -p "./det"
 
ICON_animalia="animalia.png"
ICON_bacteria="bacteria.png"
ICON_fungi="fungi.png"
ICON_chromista="chromista.png"
ICON_plantae="plantae.svg"
ICON_plostenkoid="plostenkoid.png"
ICON_protista="protista.png"
ICON_biohazard="biohazard.svg"
 
json=""
 
rss=$'<?xml version="1.0" encoding="UTF-8" ?>\n'
rss+=$'<rss version="2.0">\n'
rss+=$'<channel>\n'
rss+=$'<title>Brmlab BioOSM RSS feed</title>\n'
rss+=$'<description>New entries on BioOSM database</description>\n'
rss+=$'<link>https://bioosm.s0c4.net</link>\n'
rss+=$'<lastBuildDate></lastBuildDate>\n'
rss+=$'<pubDate></pubDate>\n'
rss+=$'<ttl>86400</ttl>\n'
 
# Return icon by Regnum
function geticon () {
	case "$1" in
		"Animalia")
			echo "$ICON_animalia";;
		"Bacteria")
			echo "$ICON_bacteria";;
		"Fungi")
			echo "$ICON_fungi";;
		"Chromista")
			echo "$ICON_chromista";;
		"Plantae")
			echo "$ICON_plantae";;
		"Protista")
			echo "$ICON_protista";;
		*)
			echo "$ICON_biohazard";;
	esac
}
 
function safehtml () {
	echo "$1" | sed -e "s/'/\&#39;/g" -e 's/"/\&#34;/g' -e 's/</\&lt;/g' -e 's/>/\&gt;/g' -e 's/^[ ]*//g' -e 's/[ ]*$//g'
}
 
i=1 # GLOBAL increment must persist multiple spagety() calls; incremented to infinity
# Core function generating entries matching selection criteria (ie Kingdom)
# !!! BEZ ODSAZENI !!!
# $1 = list of entries
# $2 = layer name
# $3 = icon of the points
function spagety () {
 
	bylo="" # Minula pozice
	sam="" # HTML samostatneho zaznamu
	osam="" # predchozi $sam
	spoj="" # HTML had z popisu stejnych pozic
	ospoj="" # Predchozi $spoj
	ox="" # Old X
	oy="" # Old Y
	datelog="" # Entries sorted by date for plaintext log
	json="var data='{\"version\":\"$(date --rfc-3339=seconds)\",\"arma\":["
 
	while IFS='' read -r radek || [[ -n "$radek" ]]; do
		co=$(echo "$radek" | grep -oe ' <title>.*</title> ' | sed -E 's/( )*<(\/)?title>( )*//g')
		co=$(safehtml "$co")
		obr=$(echo "$radek" | grep -oe ' <image>.*</image> ' | sed -E 's/( )*<(\/)?image>( )*//g' | grep -oPe '[^/]*$')
		obr=$(safehtml "$obr")
		kde=$(echo "$radek" | grep -oe '<locality>.*</locality>' | grep -oPe '[0-9]+\.[0-9]{1,10}[, ]*[0-9]+\.[0-9]{1,10}')
		kde=$(safehtml "$kde")
		kdex=$(echo "$kde" | grep -oPe '[0-9]+\.[0-9]{1,10}$')
		kdex=$(safehtml "$kdex")
		kdey=$(echo "$kde" | grep -oPe '^[0-9]+\.[0-9]{1,10}')
		kdey=$(safehtml "$kdey")
		kdy=$(echo "$radek" | grep -oe ' <taken-date>.*</taken-date> ' | sed -E 's/( )*<(\/)?taken-date>( )*//g' | sed -E 's/([0-9]+)\.([0-9]+)\.([0-9]{4})/\3-\2-\1/g' | sed -E 's/-([0-9])-/-0\1-/g' | sed -E 's/-([0-9])$/-0\1/g')
		kdy=$(safehtml "$kdy")
		skop_typ=$(echo "$radek" | grep -oe ' <new-field-1>.*</new-field-1> ' | sed -E 's/( )*<(\/)?new-field-1>( )*//g')
		skop_typ=$(safehtml "$skop_typ")
		skop=$(echo "$radek" | grep -oe ' <microscope>.*</microscope> ' | sed -E 's/( )*<(\/)?microscope>( )*//g')
		skop=$(safehtml "$skop")
		imp=$(echo "$radek" | grep -oe ' <new-field-3>.*</new-field-3> ' | sed -E 's/( )*<(\/)?new-field-3>( )*//g')
		imp=$(safehtml "$imp")
		reg=$(echo "$radek" | grep -oe ' <new-field-4>.*</new-field-4> ' | sed -E 's/( )*<(\/)?new-field-4>( )*//g')
		reg=$(safehtml "$reg")
		phy=$(echo "$radek" | grep -oe ' <phylum>.*</phylum> ' | sed -E 's/( )*<(\/)?phylum>( )*//g')
		phy=$(safehtml "$phy")
		cla=$(echo "$radek" | grep -oe ' <class>.*</class> ' | sed -E 's/( )*<(\/)?class>( )*//g')
		cla=$(safehtml "$cla")
		ord=$(echo "$radek" | grep -oe ' <order>.*</order> ' | sed -E 's/( )*<(\/)?order>( )*//g')
		ord=$(safehtml "$ord")
		fam=$(echo "$radek" | grep -oe ' <family>.*</family> ' | sed -E 's/( )*<(\/)?family>( )*//g')
		fam=$(safehtml "$fam")
		gen=$(echo "$radek" | grep -oe ' <genus>.*</genus> ' | sed -E 's/( )*<(\/)?genus( )*>//g')
		gen=$(safehtml "$gen")
		spe=$(echo "$radek" | grep -oe ' <species>.*</species> ' | sed -E 's/( )*<(\/)?species>( )*//g')
		spe=$(safehtml "$spe")
		loc=$(echo "$radek" | grep -oe ' <locality---plaintext>.*</locality---plaintext> ' | sed -E 's/( )*<(\/)?locality---plaintext>( )*//g')
		loc=$(safehtml "$loc")
		des=$(echo "$radek" | grep -oe ' <description>.*</description> ' | sed -E 's/( )*<(\/)?description>( )*//g')
		des=$(safehtml "$des")
		vid=$(echo "$radek" | grep -oe ' <videolink>.*</videolink> ' | sed -E 's/( )*<(\/)?videolink>( )*//g')
		vid=$(safehtml "$vid")
		bio=$(echo "$radek" | grep -oe ' <biotope>.*</biotope> ' | sed -E 's/( )*<(\/)?biotope>( )*//g')
		bio=$(safehtml "$bio")
		eng=$(echo "$radek" | grep -oe ' <enlargement>.*</enlargement> ' | sed -E 's/( )*<(\/)?enlargement>( )*//g')
		eng=$(safehtml "$eng")
		obs=$(echo "$radek" | grep -oe ' <observer>.*</observer> ' | sed -E 's/( )*<(\/)?observer>( )*//g')
		obs=$(safehtml "$obs")
		lnk=$(echo "$radek" | grep -oe ' <localitylink>.*</localitylink> ' | sed -E 's/( )*<(\/)?localitylink>( )*//g')
		lnk=$(safehtml "$lnk")
		har=$(echo "$radek" | grep -oe ' <harvesting-method>.*</harvesting-method> ' | sed -E 's/( )*<(\/)?harvesting-method>( )*//g')
		den=$(echo "$radek" | grep -oe ' <population-density>.*</population-density> ' | sed -E 's/( )*<(\/)?population-density>( )*//g')
		dur=$(echo "$radek" | grep -oe ' <min>.*</min> ' | sed -E 's/( )*<(\/)?min>( )*//g')
		lor=$(echo "$radek" | grep -oe ' <locality-reference>.*</locality-reference> ' | sed -E 's/( )*<(\/)?locality-reference>( )*//g')
		lrl=$(echo "$radek" | grep -oe ' <locality-reference---link>.*</locality-reference---link> ' | sed -E 's/( )*<(\/)?locality-reference---link>( )*//g')
		lov=$(echo "$radek" | grep -oe ' <locality---vobrazek>.*</locality---vobrazek> ' | sed -E 's/( )*<(\/)?locality---vobrazek>( )*//g' | grep -oPe '[^/]*$')
 
		# >&2 echo "$co - $har - $den - $dur - $lor - $lrl - $lov"
 
		detid=$(echo "brmlab$co$obr$kde$kdy" | md5sum | grep -oe '[a-zA-Z0-9]*')
 
		if [[ "$kdex" = "" ]]; then
			>&2 echo -e "\033[31m" $(echo "$radek" | grep -oe '<locality>.*</locality>') " $co\033[0m"
			continue;
		fi
		zkurvenetellico=$(echo "$obr" | grep -oe '\.[a-zA-Z]*$')
		if [[ "$zkurvenetellico" = ".jpeg" ]]; then
			>&2 echo -e "\033[31m$obr $co\033[0m"
			continue;
		fi
 
		if [[ "$spe" = "sp." ]]; then
			wikisp="https://en.wikipedia.org/wiki/$gen"
		else
			wikisp="https://en.wikipedia.org/wiki/$gen $spe"
		fi
 
		json+="{"
		json+=" \"qualis\":\"$co\","
		json+=" \"imperium\":\"$imp\","
		json+=" \"regnum\":\"$reg\","
		json+=" \"phylum\":\"$phy\","
		json+=" \"classis\":\"$cla\","
		json+=" \"ordo\":\"$ord\","
		json+=" \"familia\":\"$fam\","
		json+=" \"genus\":\"$gen\","
		json+=" \"specie\":\"$spe\","
		json+=" \"locus\":\"$kde\","
		json+=" \"x\":\"$kdex\","
		json+=" \"y\":\"$kdey\","
		json+=" \"locplain\":\"$loc\","
		json+=" \"depictio\":\"$des\","
		json+=" \"quando\":\"$kdy\","
		json+=" \"obr\":\"$obr\","
		json+=" \"micro\":\"$skop\","
		json+=" \"microtyp\":\"$skop_typ\","
		json+=" \"vid\":\"$vid\","
		json+=" \"bio\":\"$bio\","
		json+=" \"amp\":\"$eng\","
		json+=" \"spec\":\"$obs\","
		json+=" \"detid\":\"$detid\","
		json+=" \"har\":\"$har\","
		json+=" \"den\":\"$den\","
		json+=" \"dur\":\"$dur\","
		json+=" \"lor\":\"$lor\","
		json+=" \"lrl\":\"$lrl\","
		json+=" \"lov\":\"$lov\","
		json+=" \"lnk\":\"$lnk\"" # Lastone without ','
		json+="},"
 
 
		rss+=$'<item>\n'
		rss+=$'  <title>'"$co"$'</title>\n'
		rss+=$'  <description>'"$des"$'</description>\n'
		rss+=$'  <link>http://brmlab.s0c4.net/bioosm/det/'"$detid"$'.htm</link>\n'
		rss+=$'  <guid isPermaLink="false">'"$detid"$'</guid>\n'
		rss+=$'  <pubDate>'"$kdy"$'</pubDate>\n'
		rss+=$'</item>\n'
 
 
		# Generate detail page
		detid=$(echo "brmlab$co$obr$kde$kdy" | md5sum | grep -oe '[a-zA-Z0-9]*')
		detpg="<html><head>"
		detpg+="<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>"
		detpg+="<link rel='stylesheet' href='../style.css' type='text/css'>"
		detpg+="<title>Brmlab - BioOSM $co $kde</title>"
		detpg+="</head><body>"
		detpg+="<table class='dettbl'><tr>"
		detpg+="<h1>$co (<a href='$wikisp' target='_blank'>wiki</a>)</h1>"
		detpg+="<td style='width:33%;vertical-align:top'>"
		if [[ "$imp" != "" ]]; then
			detpg+="<b>Imperium:</b> <a href='https://en.wikipedia.org/wiki/$imp' target='_blank'>$imp</a><br>"
		fi
		if [[ "$reg" != "" ]]; then
			detpg+="<b>Regnum:</b> <a href='https://en.wikipedia.org/wiki/$reg' target='_blank'>$reg</a><br>"
		fi
		if [[ "$phy" != "" ]]; then
			detpg+="<b>Phylum:</b> <a href='https://en.wikipedia.org/wiki/$phy' target='_blank'>$phy</a><br>"
		fi
		if [[ "$cla" != "" ]]; then
			detpg+="<b>Classis:</b> <a href='https://en.wikipedia.org/wiki/$cla' target='_blank'>$cla</a><br>"
		fi
		if [[ "$ord" != "" ]]; then
			detpg+="<b>Ordo:</b> <a href='https://en.wikipedia.org/wiki/$ord' target='_blank'>$ord</a><br>"
		fi
		if [[ "$fam" != "" ]]; then
			detpg+="<b>Familia:</b> <a href='https://en.wikipedia.org/wiki/$fam' target='_blank'>$fam</a><br>"
		fi
		if [[ "$gen" != "" ]]; then
			detpg+="<b>Genus:</b> <a href='https://en.wikipedia.org/wiki/$gen' target='_blank'>$gen</a><br>"
		fi
		if [[ "$spe" != "" ]]; then
			detpg+="<b>Specie:</b> <a href='$wikisp' target='_blank'>$spe</a><br>"
		fi
		detpg+="<br>"
		if [[ "$kdy" != "" ]]; then
			detpg+="<b>Quando:</b> $kdy<br>"
		fi
		if [[ "$lnk" != "" ]]; then
			loc="<a href=\"$lnk\" target=\"_blank\">$loc</a>" # Yes, escaped "
		fi
		detpg+="<b>Locus:</b> $kde ($loc)<br>"
		if [[ "$obs" != "" ]]; then
			detpg+="<b>Spectator:</b> $obs<br>"
		fi
		if [[ "$bio" != "" ]]; then
			detpg+="<b>Biotope:</b> $bio<br>"
		fi
		if [[ "$skop" != "" ]]; then
			detpg+="<b>Microscopium:</b> $skop ($skop_typ)<br>"
		fi
		if [[ "$eng" != "" ]]; then
			detpg+="<b>Amplificatio:</b> $eng<br>"
		fi
		if [[ "$vid" != "" ]]; then
			detpg+="<b>Video:</b> <a href=\"$vid\" target=\"_blank\">$vid</a><br>"
		fi
		if [[ "$har" != "" ]]; then
			detpg+="<b>Collecting method:</b> $har<br>"
		fi
		if [[ "$den" != "" ]]; then
			detpg+="<b>Individuals found:</b> $den<br>"
		fi
		if [[ "$dur" != "" ]]; then
			detpg+="<b>Duration on stage:</b> $dur<br>"
		fi
		if [[ "$lrl" != "" ]]; then
			detpg+="<b>Locality reference:</b> <a href=\"$lrl\" target=\"_blank\">$lor</a><br>"
		elif [[ "$lor" != "" ]]; then
			detpg+="<b>Locality reference:</b> $lor<br>"
		fi
		if [[ "$des" != "" ]]; then
			detpg+="<b>Depictio:</b> $des<br>"
		fi
		detpg+="<br><b>More on <a href=\"../\">BioOSM map</a></b><br>"
		detpg+="<br>"
 
		lhx=$(echo "$kdex-0.022" | bc)
		lhy=$(echo "$kdey-0.010" | bc)
		pdx=$(echo "$kdex+0.022" | bc)
		pdy=$(echo "$kdey+0.010" | bc)
		detpg+="<iframe id='minimapa' src='https://www.openstreetmap.org/export/embed.html?bbox=$lhx%2C$lhy%2C$pdx%2C$pdy&amp;layer=mapnik&amp;marker=$kdey%2C$kdex'></iframe>"
		detpg+="</td><td style='min-width:66%;vertical-align:top'>"
 
		if [[ "$obr" != "" ]]; then
			detpg+="<a href=\"../img/$obr\"><img src=\"../img/$obr\" alt=\"$co\" class='detimg'></a>"
		else
			if [[ "$vid" != "" ]]; then
				detyt=$(echo "$vid" | sed -e 's/youtube.com\/watch?v=/youtube.com\/embed\//g')
				detpg+="<iframe class='detvid' src='$detyt' frameborder='0' allow='encrypted-media' allowfullscreen></iframe>"
			else
				detpg+="<img src=\"../$3\" alt=\"video\" class='detimg'>"
			fi
		fi
		if [[ "$lov" != "" ]]; then
			detpg+="<img class=\"detimg\" src=\"../lokality/$lov\" alt=\"Locality photo\"><br>"
		fi
 
		detpg+="</td></tr></table>"
		detpg+="</body></html>"
		echo "$detpg" > "./det/$detid.htm"
 
		# Plain log of entries
		datelog+="$kdy $kde <a href='./det/$detid.htm' target='_blank'>$co</a><br>\n"
 
		>&2 echo -e "\033[32m$co $obs\033[0m"
 
		ox="$kdex"
		oy="$kdey"
 
		i=$(($i+1))
 
	done <<< $(echo "$1") # Zere parametr spaget, nikoli $1 scriptu !!!
	echo "$json{}]}" | sed -e "s/^var data='//g" > "./bioosm.json"
	echo "$json{}]}'"
 
	rss+=$'</channel>\n'
	rss+=$'</rss>\n'
	echo "$rss" > "./bioosm.rss"
 
} # KONEC FCE SPAGETY
 
 
 
# Parse Tellico file to list of entries
praseTC=$(unzip -p "$1" tellico.xml | tr -d '\n' | sed -e $'s/<entry id="/\\\n<entry id="/g' -e $'s/<\/entry>/<\/entry>\\\n/g' | grep -Pe '^<entry id="' | grep "<strcit-do-mapy>yep</strcit-do-mapy>" | sed -E 's/(^.*)(<locality>.*<\/locality>)(.*$)/\2\1\3/' | sort)
 
# Sorted unique Kingdoms (to be passed as selection criteria)
kingdoms=$(echo "$praseTC" | grep -oe ' <new-field-4>.*</new-field-4> ' | sed -E 's/( )*<(\/)?new-field-4>( )*//g' | sort | uniq)
 
echo '<!DOCTYPE html>'
echo '<html>'
echo '<head>'
echo '	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'
echo '	<title>brmlab - BioOSM</title>'
echo '	<link rel="stylesheet" href="./style.css" type="text/css">'
echo '	<link rel="favicon" href="./'$ICON_biohazard'">'
echo '	<script src="./OpenLayers.js"></script>'
echo '</head>'
echo '<body>'
# Generate select
echo "<div id='plainlog'><b><a href='./bioosm.rss'>RSS feed</a><br><a href='./plainlog.htm'>Quick news log</a></b></div>"
echo "<h1 id='title'>BioOSM - arma biologica in tuis vicinia</h1>"
ksel="<select id='reg' onChange='genphy()'>"
ksel="$ksel<option value='ALL' selected>ALL</option>"
while IFS='' read -r king || [[ -n "$king" ]]; do
	ksel="$ksel<option value='"$king"'>$king</option>"
done <<< $(echo "$kingdoms")
ksel="$ksel</select>"
echo "Regnum: $ksel "
 
echo "Phylum: <select id='phy' onChange='gencla()'><option>ALL</option></select> "
echo "Classis: <select id='cla' onChange='genord()'><option>ALL</option></select> "
echo "Ordo: <select id='ord' onChange='genfam()'><option>ALL</option></select> "
echo "Familia: <select id='fam' onChange='gengen()'><option>ALL</option></select> "
echo "Genus: <select id='gen' onChange='genspe()'><option>ALL</option></select>"
echo "Specie: <select id='spe' onChange='armageddon()'><option>ALL</option></select>"
echo "<br><input type='button' value='Platyhelminthes' onClick='plostenkoidy()'>"
echo "<input type='checkbox' id='studchecker' onChange='studdrv()'>&nbsp;Springs"
#echo "<input type='button' value='Bugs' onClick='buggy()'>"
echo "<br><br><div id='map' class='smallmap'></div>"
echo "<br><p>Welcome! You can download the <a href='./bioosm.json' target='_blank'>source data as JSON file</a><br>"
echo "This site is owned by members of the <a href='https://brmlab.cz' target='_blank'>hackerspace brmlab</a>. See our wiki page for <a href='https://brmlab.cz/project/bioosm/start' target='_blank'>details and contact info</a><br>License: CC-BY-SA</p>"
echo "</body>"
 
echo "<script>"
echo 'map = new OpenLayers.Map("map");'
echo 'map.addLayer(new OpenLayers.Layer.OSM());'
echo 'epsg4326 =  new OpenLayers.Projection("EPSG:4326"); //WGS 1984 projection'
echo 'projectTo = map.getProjectionObject(); //The map projection (Spherical Mercator)'
echo 'var lonLat = new OpenLayers.LonLat(15.478, 49.817).transform(epsg4326, projectTo);'
echo 'var zoom=8;'
echo 'map.setCenter (lonLat, zoom);'
 
echo 'var vectorLayer = new OpenLayers.Layer.Vector("Overlay",{attribution:"<a href=\"http://brmlab.cz\">Brmlab</a>"});'
 
echo '// Define markers as "features" of the vector layer:'
 
echo 'var atol = new OpenLayers.Feature.Vector('
echo '	new OpenLayers.Geometry.Point(14.41876, 50.10554).transform(epsg4326, projectTo),'
echo '		{description:"Atomovy atol Brmkini"} ,'
echo '		{externalGraphic: "./biohazard.svg", graphicHeight:8, graphicWidth:8, graphicXOffset:-4, graphicYOffset:-4},'
echo ');'
echo 'vectorLayer.addFeatures(atol);'
# Sem prijdou dalsi staticke ficury
echo "map.addLayer(vectorLayer);"
 
spagety "$praseTC" "ALL" "$ICON_biohazard"
 
echo '</script>'
echo '<script src="./bioosm.js"></script>' # Must be after JSON
echo "</html>"
 
# Create plaintext log
dateloghtm="<html><head>"
dateloghtm+="<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>"
dateloghtm+="<link rel='stylesheet' href='./style.css' type='text/css'>"
dateloghtm+="<title>Brmlab - BioOSM plaintext log</title>"
dateloghtm+="</head><body>"
datelogsort=$(echo -e "$datelog" | sort -r | uniq)
dateloghtm+="$datelogsort"
dateloghtm+="</body></html>"
echo "$dateloghtm" > "./plainlog.htm"

bioosm.js

bioosm.js
var blob=JSON.parse(data)
var arma=blob.arma
var stud=JSON.parse('{}');
 
var vectorLayerDynamic = new OpenLayers.Layer.Vector('Overlay',{attribution:'<a href="http://brmlab.cz">Brmlab</a>'});
map.addLayer(vectorLayerDynamic);
var studlay = new OpenLayers.Layer.Vector("Overlay",{attribution:"<a href=\"http://brmlab.cz\">Brmlab</a>"}); // studanky
map.addLayer(studlay);
 
var regsel=document.getElementById("reg")
var physel=document.getElementById("phy")
var clasel=document.getElementById("cla")
var ordsel=document.getElementById("ord")
var famsel=document.getElementById("fam")
var gensel=document.getElementById("gen")
var spesel=document.getElementById("spe")
 
var ICON_animalia="animalia.png"
var ICON_bacteria="bacteria.png"
var ICON_fungi="fungi.png"
var ICON_chromista="chromista.png"
var ICON_plantae="plantae.svg"
var ICON_plostenkoid="plostenkoid.png"
var ICON_protista="protista.png"
var ICON_biohazard="biohazard.svg"
var ICON_studanka="studanka.png"
 
function getJSONstud()
{
	url="./stud.json";
	var request;
	if(window.XMLHttpRequest)
		request=new XMLHttpRequest();
	else
		request=new ActiveXObject("Microsoft.XMLHTTP");
	request.onreadystatechange=function()
	{
		if(request.readyState==4)
		{
			stud=JSON.parse(request.responseText);
			studdraw(stud);
		}
	}
	request.open("GET",url,true);
	request.send();
}
 
function studdraw(sj)
{
	studlay.destroyFeatures();
	sjs=stud.std;
	s=[];
 
	for(i=0;i<sjs.length;i++)
	{
		s[i] = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(sjs[i].lon,sjs[i].lat).transform(epsg4326,projectTo),{'description':"<table class=\"hadtbl\">"+sjs[i].name+"</table>"},{'externalGraphic':ICON_studanka,'graphicHeight':24,'graphicWidth':24,'graphicXOffset':-12,'graphicYOffset':-12});
		studlay.addFeatures(s[i]);
	}
}
 
function studdrv()
{
	box=document.getElementById("studchecker");
	if(box.checked)
		getJSONstud();
	else
		studlay.destroyFeatures();
}
 
// Return icon by Regnum
function geticon (a,i)
{
	var r=""
	if(document.getElementById("reg").value!="ALL")
		r=document.getElementById("reg").value
	else
	{
		r=a[i].regnum
		for(var e=i;e>=0 && a[e].locus==a[i].locus;e--)
			if(a[e].regnum!=a[i].regnum)
			{
				r="ALL";
				break;
			}
	}
 
	switch (r)
	{
		case "Animalia":
			return ICON_animalia;
		case "Bacteria":
			return ICON_bacteria;
		case "Fungi":
			return ICON_fungi;
		case "Chromista":
			return ICON_chromista;
		case "Plantae":
			return ICON_plantae;
		case "Protista":
			return ICON_protista;
		default:
			return ICON_biohazard
	}
}
 
function genphy() {
	physel.innerHTML="<option>ALL</option>"
	clasel.innerHTML="<option>ALL</option>"
	ordsel.innerHTML="<option>ALL</option>"
	famsel.innerHTML="<option>ALL</option>"
	gensel.innerHTML="<option>ALL</option>"
	spesel.innerHTML="<option>ALL</option>"
 
	var phyarr=[]
	for (var i=0;i<arma.length-1;i++)
	{
		if(regsel.value==arma[i].regnum && arma[i].phynum!="")
			phyarr.push(arma[i].phylum)
	}
	phyarr.sort()
	for (var i=0;i<phyarr.length;i++)
	{
		if(i==0)
		{
			physel.innerHTML+="<option>"+phyarr[0]+"</option>"
			continue
		}
		if(phyarr[i]!=phyarr[i-1])
			physel.innerHTML+="<option>"+phyarr[i]+"</option>"
	}
	armageddon() // Populate the map with monsters...
}
 
function gencla() {
	clasel.innerHTML="<option>ALL</option>"
	ordsel.innerHTML="<option>ALL</option>"
	famsel.innerHTML="<option>ALL</option>"
	gensel.innerHTML="<option>ALL</option>"
	spesel.innerHTML="<option>ALL</option>"
 
	var claarr=[]
	for (var i=0;i<arma.length-1;i++)
	{
		if(physel.value==arma[i].phylum && arma.classis!="")
			claarr.push(arma[i].classis)
	}
	claarr.sort()
	for (var i=0;i<claarr.length;i++)
	{
		if(i==0)
		{
			clasel.innerHTML+="<option>"+claarr[0]+"</option>"
			continue
		}
		if(claarr[i]!=claarr[i-1])
			clasel.innerHTML+="<option>"+claarr[i]+"</option>"
	}
	armageddon() // Populate the map with monsters...
}
 
function genord() {
	ordsel.innerHTML="<option>ALL</option>"
	famsel.innerHTML="<option>ALL</option>"
	gensel.innerHTML="<option>ALL</option>"
	spesel.innerHTML="<option>ALL</option>"
	var ordarr=[]
	for (var i=0;i<arma.length-1;i++)
	{
		if(clasel.value==arma[i].classis && arma[i].ordo!="")
			ordarr.push(arma[i].ordo)
	}
	ordarr.sort()
	for (var i=0;i<ordarr.length;i++)
	{
		if(i==0)
		{
			ordsel.innerHTML+="<option>"+ordarr[0]+"</option>"
			continue
		}
		if(ordarr[i]!=ordarr[i-1])
			ordsel.innerHTML+="<option>"+ordarr[i]+"</option>"
	}
	armageddon() // Populate the map with monsters...
}
 
function genfam() {
	famsel.innerHTML="<option>ALL</option>"
	gensel.innerHTML="<option>ALL</option>"
	spesel.innerHTML="<option>ALL</option>"
	var famarr=[]
	for (var i=0;i<arma.length-1;i++)
	{
		if(ordsel.value==arma[i].ordo && arma[i].familia!="")
			famarr.push(arma[i].familia)
	}
	famarr.sort()
	for (var i=0;i<famarr.length;i++)
	{
		if(i==0)
		{
			famsel.innerHTML+="<option>"+famarr[0]+"</option>"
			continue
		}
		if(famarr[i]!=famarr[i-1])
			famsel.innerHTML+="<option>"+famarr[i]+"</option>"
	}
	armageddon() // Populate the map with monsters...
}
 
function gengen() {
	gensel.innerHTML="<option>ALL</option>"
	spesel.innerHTML="<option>ALL</option>"
	var genarr=[]
	for (var i=0;i<arma.length-1;i++)
	{
		if(famsel.value==arma[i].familia && arma[i].genus!="")
			genarr.push(arma[i].genus)
	}
	genarr.sort()
	for (var i=0;i<genarr.length;i++)
	{
		if(i==0)
		{
			gensel.innerHTML+="<option>"+genarr[0]+"</option>"
			continue
		}
		if(genarr[i]!=genarr[i-1])
			gensel.innerHTML+="<option>"+genarr[i]+"</option>"
	}
	//genspe() // ...and here we go
	armageddon() // Populate the map with monsters...
}
 
function genspe()
{
	spesel.innerHTML="<option>ALL</option>"
	var spearr=[]
	for (var i=0;i<arma.length-1;i++)
	{
		if(gensel.value==arma[i].genus && arma[i].specie!="")
			spearr.push(arma[i].specie)
	}
	spearr.sort()
	for (var i=0;i<spearr.length;i++)
	{
		if(i==0)
		{
			spesel.innerHTML+="<option>"+spearr[0]+"</option>"
			continue
		}
		if(spearr[i]!=spearr[i-1])
			spesel.innerHTML+="<option>"+spearr[i]+"</option>"
	}
	armageddon() // Populate the map with monsters...
}
 
function armageddon()
{
	var speval=document.getElementById("spe").value
	var genval=document.getElementById("gen").value
	var famval=document.getElementById("fam").value
	var ordval=document.getElementById("ord").value
	var claval=document.getElementById("cla").value
	var phyval=document.getElementById("phy").value
	var regval=document.getElementById("reg").value
	var a=[]
 
	if(speval!="ALL")
	{
		for(var i=0;i<arma.length-1;i++)
			if(arma[i].specie==speval && arma[i].genus==genval) // Check genus because of unknown "sp."
				a.push(arma[i])
	}
	else if(genval!="ALL")
	{
		for(var i=0;i<arma.length-1;i++)
			if(arma[i].genus==genval)
				a.push(arma[i])
	}
	else if(famval!="ALL")
	{
		for(var i=0;i<arma.length-1;i++)
			if(arma[i].familia==famval)
				a.push(arma[i])
	}
	else if(ordval!="ALL")
	{
		for(var i=0;i<arma.length-1;i++)
			if(arma[i].ordo==ordval)
				a.push(arma[i])
	}
	else if(claval!="ALL")
	{
		for(var i=0;i<arma.length-1;i++)
			if(arma[i].classis==claval)
				a.push(arma[i])
	}
	else if(phyval!="ALL")
	{
		for(var i=0;i<arma.length-1;i++)
			if(arma[i].phylum==phyval)
				a.push(arma[i])
	}
	else if(regval!="ALL")
	{
		for(var i=0;i<arma.length-1;i++)
			if(arma[i].regnum==regval)
				a.push(arma[i])
	}
	else // Regnum: ALL
	{
		for(var i=0;i<arma.length-1;i++)
			a.push(arma[i])
	}
 
	icongeddon(a)
}
 
function buggy()
{
	var p=[]
	for(var i=0;i<arma.length-1;i++)
	{
		if(arma[i].regnum==""||
	     arma[i].phylum==""||
	     arma[i].classis==""||
	     arma[i].ordo==""||
	     arma[i].familia==""||
	     arma[i].genus=="")
		  p.push(arma[i])
	}
	icongeddon(p)
}
 
function plostenkoidy()
{
	var p=[]
	for(var i=0;i<arma.length-1;i++)
	{
		if(arma[i].phylum=="Platyhelminthes")
			p.push(arma[i])
	}
	icongeddon(p)
}
 
function icongeddon(a)
{
	//alert(a.length) // #thingies to show in the map'
	while(map.popups.length)
		map.removePopup(map.popups[0])
	vectorLayerDynamic.destroyFeatures()
 
	var bylo="" // Minula pozice
	var sam="" // HTML samostatneho zaznamu
	var osam="" // predchozi $sam
	var spoj="" // HTML had z popisu stejnych pozic
	var ospoj="" // Predchozi spoj
	var ox="" // Old X
	var oy="" // Old Y
	var datelog="" // Entries sorted by date for plaintext log
	var i=0 // Iterator over a[] (needed after FOR)
	var n=[] // New points in the layer
	var muchicons=0 // How much Regnum's?
	var samicon=ICON_biohazard // Icon
	var spojicon=ICON_biohazard // Icon
 
	for(;i<a.length;i++) // -1 fix for last empty entry
	{
		// Pokracujem v hadovi
		if(a[i].locus == bylo)
		{
			sam="";
			spoj+="<tr><td>"
			spoj+='<a href="./det/'+a[i].detid+'.htm" target="_blank">'
			if(a[i].obr != "")
				spoj+='<img src="./simg/'+a[i].obr+'" class="hadimg"></a></td>'
			else
				spoj+='<img src=./"'+ICON_biohazard+'" class="hadimg"></a></td>'
			spoj+="<td>"+a[i].qualis+"<br>"+a[i].quando+"</td>"
			spoj+="</tr>"
			ox=a[i].x
			oy=a[i].y
			continue;
		}
 
		if(a[i].specie=="sp.")
			wikisp="https://en.wikipedia.org/wiki/"+a[i].genus
		else
			wikisp="https://en.wikipedia.org/wiki/"+a[i].genus+" "+a[i].specie
 
		// Bud prvni zaznam, nebo zmena pozice
 
		// Predchozi pozice jen 1 zaznam?
		if(sam != "")
		{
			samicon=geticon(a,i-1)
			n[i] = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(ox,oy).transform(epsg4326,projectTo),{'description':sam},{'externalGraphic':samicon,'graphicHeight':24,'graphicWidth':24,'graphicXOffset':-12,'graphicYOffset':-12});
			vectorLayerDynamic.addFeatures(n[i]);
			spoj=""
			sam=""
		} // ELSE vytvori prazdny radek
		// Predchozi pozice vic zaznamu?
		if(spoj!="")
		{
			spojicon=geticon(a,i-1)
			n[i] = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(ox,oy).transform(epsg4326,projectTo),{'description':"<table class=\"hadtbl\">"+spoj+"</table>"},{'externalGraphic':spojicon,'graphicHeight':24,'graphicWidth':24,'graphicXOffset':-12,'graphicYOffset':-12});
			vectorLayerDynamic.addFeatures(n[i]);
			spoj=""
			sam=""
		}
 
		bylo=a[i].locus
		spoj='<tr><td><a href="./det/'+a[i].detid+'.htm" target="_blank">'
		if(a[i].obr != "")
			spoj+='<img src="./simg/'+a[i].obr+'" class="hadimg"></a></td>'
		else
			spoj+='<img src="./'+geticon(a,i)+'" class="hadimg"</a></td>'
		spoj+='<td>'+a[i].qualis+'<br>'+a[i].quando+'</td>'
		spoj+="</tr>"
 
 
		sam='<a href="./det/'+a[i].detid+'.htm" target="_blank"><img src="./simg/'+a[i].obr+'" alt="'+a[i].qualis+'" class="buttimg"></a>'
		sam+='<br><span class="butttext">'
		sam+='<b>Qualis:</b> <a href="'+wikisp+'" target="_blank">'+a[i].qualis+'</a><br>'
		if(a[i].imperium != "")
			sam+='<b>Imperium:</b> <a href="https://en.wikipedia.org/wiki/'+a[i].imperium+'" target="_blank">'+a[i].imperium+'</a><br>'
		if(a[i].regnum != "")
    	sam+='<b>Regnum:</b> <a href="https://en.wikipedia.org/wiki/'+a[i].regnum+'" target="_blank">'+a[i].regnum+'</a><br>'
		if(a[i].phylum != "")
			sam+='<b>Phylum:</b> <a href="https://en.wikipedia.org/wiki/'+a[i].phylum+'" target="_blank">'+a[i].phylum+'</a><br>'
		if(a[i].classis != "")
			sam+='<b>Classis:</b> <a href="https://en.wikipedia.org/wiki/'+a[i].classis+'" target="_blank">'+a[i].classis+'</a><br>'
		if(a[i].ordo != "")
			sam+='<b>Ordo:</b> <a href="https://en.wikipedia.org/wiki/'+a[i].ordo+'" target="_blank">'+a[i].ordo+'</a><br>'
		if(a[i].familia != "")
			sam+='<b>Familia:</b> <a href="https://en.wikipedia.org/wiki/'+a[i].familia+'" target="_blank">'+a[i].familia+'</a><br>'
		if(a[i].genus != "")
			sam+='<b>Genus:</b> <a href="https://en.wikipedia.org/wiki/'+a[i].genus+'" target="_blank">'+a[i].genus+'</a><br>'
		if(a[i].specie != "")
			sam+='<b>Specie:</b> <a href="'+wikisp+'" target="_blank">'+a[i].specie+'</a><br>'
		if(a[i].bio != "")
			sam+="<b>Biotope:</b> "+a[i].bio+"<br>"
		if(a[i].quando != "")
			sam+="<b>Quando:</b> "+a[i].quando+"<br>"
		sam+="<b>Locus:</b> "+a[i].locus+" ("+a[i].locplain+")<br>"
		if(a[i].spec != "")
 			sam+="<b>Spectator:</b> "+a[i].spec+"<br>"
		if(a[i].micro != "")
			sam+="<b>Microscopium:</b> "+a[i].micro+" ("+a[i].microtyp+")<br>"
		if(a[i].amp != "")
			sam+="<b>Amplificatio:</b> "+a[i].amp+"<br>"
		/* if [[ "$des" != "" ]]; then
		#   sam="$sam<b>Depictio:</b> $des<br>"
		# fi */
		if(a[i].vid != "")
			sam+='<b>Video:</b> <a href="'+a[i].vid+'" target="_blank">'+a[i].vid+'</a><br>'
		sam+="</span>"
 
		ox=a[i].x
		oy=a[i].y
	} // Konec prochazeni a[]
 
	// Do not forget to print last line when FOR ends!
	samicon=geticon(a,i-1)
	if(sam == "")
		sam='<table style="hadtbl">'+spoj+'</table>'
 
	n[i]=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(a[i-1].x,a[i-1].y).transform(epsg4326,projectTo),{description:"'"+sam+"'"},{externalGraphic:samicon,graphicHeight:24,graphicWidth:24,graphicXOffset:-12,graphicYOffset:-12});
	vectorLayerDynamic.addFeatures(n[i]);
 
} // Konec armageddonu
 
var laycon = [vectorLayer,vectorLayerDynamic,studlay];
 
var controls = {selector: new OpenLayers.Control.SelectFeature(laycon, { onSelect: createPopup, onUnselect: destroyPopup })};
map.addControl(controls['selector']);
controls['selector'].activate();
 
function createPopup(feature)
{
	feature.popup = new OpenLayers.Popup.FramedCloud('pop',
		feature.geometry.getBounds().getCenterLonLat(),
		null,
		'<div class="markerContent">'+feature.attributes.description+'</div>',
		null,
		false, // Close button?
		function() { controls['selector'].unselectAll(); }
	);
	//feature.popup.closeOnMove = true;
	map.addPopup(feature.popup);
}
 
function destroyPopup(feature) {
	feature.popup.destroy();
	feature.popup = null;
}
 
// Run armageddon on initial load
armageddon()

Springs

To be able to better plan routes for collecting planarians, the knowledge of locations of springs seems to be important. So BioOSM can show them! Below is a script to get the locations from OSM XMLs obtainable from http://osm.kyblsoft.cz/archiv/.

studanky.sh
#!/bin/bash
# generate BioOSM compatible "springs"
# Usage: studanky.sh osmdump.xml
# 
# Download OSM file to be passed as $1
# wget "http://osm.kyblsoft.cz/archiv/czech_republic-2019-11-03.osm.gz"
# gzip -kd ./czech_republic-2019-11-03.osm.gz
#
# Pozor ^^ sezere spoustu rameti
#
 
osm=$(cat "$1" | sed -e 's/<node/\'$'\a<node/g' -e 's/<\/node>/<\/node\'$'\a/g' -e 's/<way/\'$'\a<way/g' -e 's/<\/way>/<\/way>\'$'\a/g' -e 's/<relation/\'$'\a<relation/g' -e 's/<\/relation>/<\/relation>\'$'\a/g' | tr -d '\n' | tr '\a' '\n' | grep 'v="spring"' | grep 'k="natural"')
 
json='{"version":"'$(date --rfc-3339=seconds)'","std":['
 
while IFS='' read -r spr || [[ -n "$spr" ]]; do
	n=$(echo "$spr" | grep -oPe 'k="name" v="[^"]*"' | sed -e 's/k="name" v="//g' -e 's/"$//g')
	lat=$(echo "$spr" | grep -oPe ' lat="[^"]*"' | sed -e 's/ lat="//g' -e 's/"$//g')
	lon=$(echo "$spr" | grep -oPe ' lon="[^"]*"' | sed -e 's/ lon="//g' -e 's/"$//g')
 
	if [ "$lat" = "" ] || [ "$lon" = "" ]; then
		continue; # <way> a tak
	fi
	if [[ "$n" = "" ]]; then
		n="inkognito"
		>&2 echo -e "\033[34m $lat $lon \033[0m";
	fi
 
	json+="{"
	json+=" \"name\":\"$n\","
	json+=" \"lon\":\"$lon\","
	json+=" \"lat\":\"$lat\""
	json+="},"
 
	>&2 echo -e "\033[32m $n $lat $lon\033[0m"
 
done <<< $(echo "$osm")
 
echo "$json{}]}"
project/bioosm/start.1573586016.txt.gz · Last modified: 2019/11/12 19:13 by sachy