Commit fcf1e123 authored by Matija Obreza's avatar Matija Obreza

Country and organization institute maps

parent fbbb2d71
......@@ -21,6 +21,9 @@ import java.util.List;
import java.util.Locale;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.FaoInstitute;
import com.fasterxml.jackson.databind.node.ArrayNode;
public interface GeoService {
......@@ -70,4 +73,6 @@ public interface GeoService {
*/
Country getCurrentCountry(String code3);
ArrayNode toJson(List<FaoInstitute> members);
}
......@@ -31,6 +31,7 @@ import org.genesys2.geo.sources.CountryInfo;
import org.genesys2.geo.sources.DavrosCountrySource;
import org.genesys2.geo.sources.GeoNamesCountrySource;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.persistence.domain.CountryRepository;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.GeoService;
......@@ -40,6 +41,10 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@Service
@Transactional(readOnly = true)
public class GeoServiceImpl implements GeoService {
......@@ -287,4 +292,23 @@ public class GeoServiceImpl implements GeoService {
countryRepository.save(country);
return country;
}
@Override
public ArrayNode toJson(List<FaoInstitute> members) {
// Generate JSON
ObjectMapper mapper = new ObjectMapper();
ArrayNode jsonArray = mapper.createArrayNode();
for (FaoInstitute inst : members) {
if (inst.getLatitude() != null) {
ObjectNode instNode = mapper.createObjectNode();
instNode.put("lat", inst.getLatitude());
instNode.put("lng", inst.getLongitude());
instNode.put("alt", inst.getAltitude());
instNode.put("title", inst.getFullName());
instNode.put("code", inst.getCode());
jsonArray.add(instNode);
}
}
return jsonArray;
}
}
......@@ -17,8 +17,10 @@
package org.genesys2.server.servlet.controller;
import java.util.HashMap;
import java.util.List;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.GeoService;
......@@ -83,6 +85,18 @@ public class CountryController extends BaseController {
return "/country/details";
}
@RequestMapping("/{country}/map")
public String map(ModelMap model, @PathVariable(value = "country") String countryStr) {
view(model, countryStr);
@SuppressWarnings("unchecked")
List<FaoInstitute> institutes = (List<FaoInstitute>) model.get("faoInstitutes");
model.addAttribute("jsonInstitutes", geoService.toJson(institutes).toString());
return "/country/map";
}
@PreAuthorize("hasRole('ADMINISTRATOR')")
@RequestMapping("/{country}/edit")
public String edit(ModelMap model, @PathVariable(value = "country") String countryStr) {
......
......@@ -27,6 +27,7 @@ import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.model.impl.Organization;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.GeoService;
import org.genesys2.server.service.OrganizationService;
import org.genesys2.server.service.TaxonomyService;
import org.genesys2.spring.ResourceNotFoundException;
......@@ -42,6 +43,10 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@Controller
@Scope("request")
@RequestMapping("/org")
......@@ -62,6 +67,10 @@ public class OrganizationController extends BaseController {
@Autowired
private ContentService contentService;
@Autowired
private GeoService geoService;
@RequestMapping("/")
public String view(ModelMap model, @RequestParam(value = "page", required = false, defaultValue = "1") int page) {
model.addAttribute("pagedData", organizationService.list(new PageRequest(page - 1, 50, new Sort("title"))));
......@@ -75,20 +84,20 @@ public class OrganizationController extends BaseController {
if (organization == null) {
throw new ResourceNotFoundException();
}
List<FaoInstitute> members=organizationService.getMembers(organization);
List<FaoInstitute> members = organizationService.getMembers(organization);
_logger.debug("Has: " + members.size());
// Sort members by country
final Locale locale = getLocale();
Collections.sort(members, new Comparator<FaoInstitute>() {
@Override
public int compare(FaoInstitute o1, FaoInstitute o2) {
return o1.getCountry().getName(locale).compareTo(o2.getCountry().getName(locale));
}
});
model.addAttribute("organization", organization);
model.addAttribute("members", members);
......@@ -110,6 +119,25 @@ public class OrganizationController extends BaseController {
return "/organization/edit";
}
/**
* View map of member institutes
*
* @param model
* @param slug
* @return
*/
@RequestMapping("/{slug}/map")
public String map(ModelMap model, @PathVariable(value = "slug") String slug) {
view(model, slug);
@SuppressWarnings("unchecked")
List<FaoInstitute> members = (List<FaoInstitute>) model.get("members");
model.addAttribute("jsonInstitutes", geoService.toJson(members).toString());
return "/organization/map";
}
@PreAuthorize("hasRole('ADMINISTRATOR')")
@RequestMapping(value = "/{slug}/update")
public String update(ModelMap model, @PathVariable(value = "slug") String slug, @RequestParam(value = "slug") String newSlug,
......@@ -123,7 +151,7 @@ public class OrganizationController extends BaseController {
} else {
organization = organizationService.update(organization.getId(), newSlug, title);
}
organizationService.updateBlurp(organization, blurp, getLocale());
return "redirect:/org/" + organization.getSlug();
......
......@@ -286,3 +286,4 @@ oauth-client.active-tokens=List of tokens issued
maps.loading-map=Loading map...
maps.view-map=View map
......@@ -21,7 +21,11 @@
</c:if>
</div>
</c:if>
<div class="page-header">
<a href="<c:url value="/geo/${country.code3.toLowerCase()}/map" />"><spring:message code="maps.view-map" /></a>
</div>
<div class="jumbotron">
<spring:message code="country.stat.countByOrigin" arguments="${countByOrigin}" />
<c:if test="${countByOrigin gt 0}">
......@@ -48,6 +52,7 @@
<a target="_blank" rel="nofollow" href="<c:out value="${country.wikiLink}" />"><c:out value="${country.wikiLink}" /></a>
</div>
</c:if>
<%-- <h3>
<spring:message code="country.statistics" />
</h3>
......
<!DOCTYPE html>
<%@include file="/WEB-INF/jsp/init.jsp"%>
<html>
<head>
<title><spring:message code="country.page.profile.title" arguments="${country.getName(pageContext.response.locale)}" argumentSeparator="|" /></title>
</head>
<body>
<h1>
<c:out value="${country.getName(pageContext.response.locale)}" />
<img class="country-flag bigger" src="${cdnFlagsUrl}/${country.code3.toUpperCase()}.png" />
</h1>
<div class="page-header">
<a href="<c:url value="/geo/${country.code3.toLowerCase()}" />"><c:out value="${country.getName(pageContext.response.locale)}" /></a>
</div>
<c:if test="${jsonInstitutes ne null}">
<div class="row" style="">
<div class="col-sm-12">
<div id="map" class="gis-map gis-map-square"><spring:message code="maps.loading-map" /></div>
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function() {
GoogleMaps.map("${pageContext.response.locale.language}", $("#map"), {
maxZoom: 8,
center: new GoogleMaps.LatLng(0, 0)
}, function(el, map) {
// info window
var infowindow = new google.maps.InfoWindow({
content: "",
maxWidth: 500
});
// markers
var jsonInstitutes=${jsonInstitutes};
jsonInstitutes.forEach(function(inst) {
var m=new google.maps.Marker({
position: new google.maps.LatLng(inst.lat, inst.lng),
title: inst.title,
map: map
});
google.maps.event.addListener(m, "click", function() {
infowindow.close();
infowindow.setContent("<a href='<c:url value="/wiews/" />" + inst.code.toLowerCase() + "'>"+inst.title+"</a>");
infowindow.open(map, m);
});
});
map.fitBounds(GoogleMaps.boundingBox(jsonInstitutes));
});
});
</script>
</c:if>
</body>
</html>
\ No newline at end of file
......@@ -21,6 +21,7 @@
<div class="page-header">
<a href="<c:url value="/org/${organization.slug}/map" />"><spring:message code="maps.view-map" /></a>
<a href="<c:url value="/org/${organization.slug}/data" />"><spring:message code="view.accessions" /></a>
</div>
......@@ -43,29 +44,29 @@
</div>
</div>
<c:remove var="countryName" />
</div>
<c:set value="" var="countryName" />
<ul class="funny-list">
<c:forEach items="${members}" var="faoInstitute" varStatus="status">
<c:if test="${countryName ne faoInstitute.country.getName(pageContext.response.locale)}">
<c:set var="countryName" value="${faoInstitute.country.getName(pageContext.response.locale)}" />
<li class="hoofdleter" id="nav-${faoInstitute.country.code3}"><c:out value="${countryName}" /> <small><a href="#"><spring:message code="jump-to-top" /></a></small></li>
</c:if>
<li class="clearfix ${status.count % 2 == 0 ? 'even' : 'odd'}"><a class="show pull-left" href="<c:url value="/wiews/${faoInstitute.code.toLowerCase()}" />"><b><c:out value="${faoInstitute.code}" /></b> <c:out value="${faoInstitute.fullName}" /></a>
<div class="pull-right">
<spring:message code="faoInstitute.accessionCount" arguments="${faoInstitute.accessionCount}" />
</div></li>
</c:forEach>
</ul>
<c:set value="" var="countryName" />
<ul class="funny-list">
<c:forEach items="${members}" var="faoInstitute" varStatus="status">
<c:if test="${countryName ne faoInstitute.country.getName(pageContext.response.locale)}">
<c:set var="countryName" value="${faoInstitute.country.getName(pageContext.response.locale)}" />
<li class="hoofdleter" id="nav-${faoInstitute.country.code3}"><c:out value="${countryName}" /> <small><a href="#"><spring:message code="jump-to-top" /></a></small></li>
</c:if>
<li class="clearfix ${status.count % 2 == 0 ? 'even' : 'odd'}"><a class="show pull-left" href="<c:url value="/wiews/${faoInstitute.code.toLowerCase()}" />"><b><c:out value="${faoInstitute.code}" /></b> <c:out value="${faoInstitute.fullName}" /></a>
<div class="pull-right">
<spring:message code="faoInstitute.accessionCount" arguments="${faoInstitute.accessionCount}" />
</div></li>
</c:forEach>
</ul>
<script type="text/javascript">
jQuery(document).ready(function() {
$("#countryNavigation").on("change", function() {
window.location.hash="nav-" + this.value;
});
<script type="text/javascript">
jQuery(document).ready(function() {
$("#countryNavigation").on("change", function() {
window.location.hash="nav-" + this.value;
});
});
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<%@include file="/WEB-INF/jsp/init.jsp"%>
<html>
<head>
<title><spring:message code="organization.page.profile.title" arguments="${organization.slug}" argumentSeparator="|" /></title>
</head>
<body>
<h1>
<c:out value="${organization.title}" />
<small><c:out value="${organization.slug}" /></small>
</h1>
<div class="page-header">
<a href="<c:url value="/org/${organization.slug}" />"><c:out value="${organization.slug}" /></a>
<a href="<c:url value="/org/${organization.slug}/map" />"><spring:message code="maps.view-map" /></a>
<a href="<c:url value="/org/${organization.slug}/data" />"><spring:message code="view.accessions" /></a>
</div>
<c:if test="${jsonInstitutes ne null}">
<div class="row" style="">
<div class="col-sm-12">
<div id="map" class="gis-map gis-map-square"><spring:message code="maps.loading-map" /></div>
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function() {
GoogleMaps.map("${pageContext.response.locale.language}", $("#map"), {
maxZoom: 8,
center: new GoogleMaps.LatLng(0, 0)
}, function(el, map) {
// info window
var infowindow = new google.maps.InfoWindow({
content: "",
maxWidth: 500
});
// markers
var jsonInstitutes=${jsonInstitutes};
jsonInstitutes.forEach(function(inst) {
var m=new google.maps.Marker({
position: new google.maps.LatLng(inst.lat, inst.lng),
title: inst.title,
map: map
});
google.maps.event.addListener(m, "click", function() {
infowindow.close();
infowindow.setContent("<a href='<c:url value="/wiews/" />" + inst.code.toLowerCase() + "'>"+inst.title+"</a>");
infowindow.open(map, m);
});
});
map.fitBounds(GoogleMaps.boundingBox(jsonInstitutes));
});
});
</script>
</c:if>
</body>
</html>
\ No newline at end of file
......@@ -25,6 +25,10 @@
margin-top: 5px;
width: 250px;
}
.gis-map.gis-map-square {
height: 100%;
}
}
@media(max-width: 780px) {
......@@ -39,6 +43,9 @@
width: 250px;
}
.gis-map.gis-map-square {
height: 100%;
}
}
@media (max-width: 500px) {
......@@ -72,6 +79,10 @@
#crops-menu .funny-list {
display: none;
}
.gis-map.gis-map-square {
height: 100%;
}
}
a {
......@@ -542,7 +553,3 @@ tr.acn .sel.picked {
height: 300px;
margin-top: 1em;
}
.gis-map.gis-map-400 {
height: 400px;
}
......@@ -24,7 +24,7 @@ GoogleMaps = {
GoogleMaps = {
LatLng: GoogleMaps.LatLng,
loaded: false,
maps: [],
queue: [],
loadedMaps: [],
googleMaps: [],
defaultOptions: {
......@@ -34,19 +34,20 @@ GoogleMaps = {
streetViewControl: false
},
map: function(language, doms, mapOptions) {
var mapOpt = {
zoom: mapOptions.zoom || this.defaultOptions.zoom,
maxZoom: mapOptions.maxZoom,
center: mapOptions.center || this.defaultOptions.center,
mapTypeId: mapOptions.mapTypeId || this.defaultOptions.mapTypeId,
markerTitle: mapOptions.markerTitle || null,
streetViewControl: mapOptions.streetViewControl || this.defaultOptions.streetViewControl
};
map: function(language, doms, mapOptions, callback) {
var mapOpt = $.extend({}, this.defaultOptions, mapOptions);
// var mapOpt = {
// zoom: mapOptions.zoom || this.defaultOptions.zoom,
// maxZoom: mapOptions.maxZoom,
// center: mapOptions.center || this.defaultOptions.center,
// mapTypeId: mapOptions.mapTypeId || this.defaultOptions.mapTypeId,
// markerTitle: mapOptions.markerTitle || null,
// streetViewControl: mapOptions.streetViewControl || this.defaultOptions.streetViewControl
// };
doms.each(function(idx,el) {
if ($.inArray(el, this.loadedMaps) < 0) {
el.googleMapsOptions = mapOpt;
GoogleMaps.maps.push(el);
// el.googleMapsOptions = mapOpt;
GoogleMaps.queue.push({element: el, mapOptions: $.extend({}, mapOpt), callback: callback});
}
});
......@@ -66,23 +67,40 @@ GoogleMaps = {
},
onLoad: function() {
var el=this.maps.shift();
while (el != null) {
var mapOptions=el.googleMapsOptions;
el.googleMapsOptions=null;
var config=this.queue.shift();
while (config != null) {
var mapOptions=config.mapOptions;
var pos=mapOptions.center;
mapOptions.center=new google.maps.LatLng(pos.lat, pos.lng, pos.noWrap);
var map = new google.maps.Map(el, mapOptions);
this.googleMaps.push(map);
var map = new google.maps.Map(config.element, mapOptions);
// this.googleMaps.push(map);
// debugger;
var marker = new google.maps.Marker({
position: mapOptions.center,
map: map,
title: mapOptions.markerTitle
});
this.loadedMaps.push(el);
el=this.maps.shift();
if (mapOptions.markerTitle != null) {
var marker = new google.maps.Marker({
position: mapOptions.center,
map: map,
title: mapOptions.markerTitle
});
}
if (config.callback != null) {
config.callback(config.element, map);
}
this.loadedMaps.push(config.element);
config=this.queue.shift();
}
},
boundingBox: function(latLngArray) {
var sw=new GoogleMaps.LatLng(180, 180);
var ne=new GoogleMaps.LatLng(-180, -180);
latLngArray.forEach(function(latLng) {
sw.lat=Math.min(sw.lat, latLng.lat);
sw.lng=Math.min(sw.lng, latLng.lng);
ne.lat=Math.max(ne.lat, latLng.lat);
ne.lng=Math.max(ne.lng, latLng.lng);
});
return new google.maps.LatLngBounds(new google.maps.LatLng(sw.lat, sw.lng), new google.maps.LatLng(ne.lat, ne.lng));
}
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment