Skip to content

Commit

Permalink
list organizations in geojson format
Browse files Browse the repository at this point in the history
  • Loading branch information
ahakanzn committed Aug 12, 2024
1 parent b75ec4a commit 6680b29
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
*/
package org.gbif.registry.ws.it;

import java.math.BigDecimal;

import org.gbif.api.model.common.paging.PagingRequest;
import org.gbif.api.model.common.paging.PagingResponse;
import org.gbif.api.model.registry.Dataset;
Expand Down Expand Up @@ -44,9 +46,13 @@
import javax.annotation.Nullable;

import org.apache.commons.beanutils.BeanUtils;
import org.geojson.Feature;
import org.geojson.FeatureCollection;
import org.geojson.Point;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.locationtech.jts.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.server.LocalServerPort;

Expand Down Expand Up @@ -266,6 +272,34 @@ public void testList(ServiceType serviceType) {
assertResultsOfSize(service.listDeleted(searchParams), 1);
}

@ParameterizedTest
@EnumSource(ServiceType.class)
public void testListPublishersAsGeoJson(ServiceType serviceType) {
OrganizationService service = (OrganizationService) getService(serviceType);

Node node = testDataFactory.newNode();
UUID nodeKey = nodeResource.create(node);

Organization o1 = testDataFactory.newOrganization(nodeKey);
o1.setTitle("n1");
o1.setEndorsementApproved(true);
o1.setLatitude(BigDecimal.valueOf(50d));
o1.setLongitude(BigDecimal.valueOf(12d));

UUID key1 = getService(serviceType).create(o1);

FeatureCollection expectedFeatureCollection = new FeatureCollection();
Feature f1 = new Feature();
f1.setGeometry(new Point(12d, 50d));
f1.setProperty("organization", "n1");
f1.setProperty("key", key1.toString());
expectedFeatureCollection.add(f1);

OrganizationRequestSearchParams searchParams = new OrganizationRequestSearchParams();
FeatureCollection result = service.listGeoJson(searchParams);
Assert.equals(expectedFeatureCollection.getFeatures().size(),result.getFeatures().size());
}

private void createOrgs(UUID nodeKey, ServiceType serviceType, Country... countries) {
OrganizationService service = (OrganizationService) getService(serviceType);
for (Country c : countries) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.gbif.registry.persistence.mapper.collections.external.IDigBioCollectionDto;
import org.gbif.registry.persistence.mapper.collections.external.IdentifierDto;
import org.gbif.registry.persistence.mapper.collections.external.MachineTagDto;
import org.gbif.registry.persistence.mapper.dto.OrganizationGeoJsonDto;
import org.gbif.registry.persistence.mapper.handler.*;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
Expand Down Expand Up @@ -221,6 +222,9 @@ ConfigurationCustomizer mybatisConfigCustomizer() {
configuration
.getTypeAliasRegistry()
.registerAlias("UserIdsTypeHandler", UserIdsTypeHandler.class);
configuration
.getTypeAliasRegistry()
.registerAlias("OrganizationGeoJsonDto", OrganizationGeoJsonDto.class);

// external iDigBio
configuration.getTypeAliasRegistry().registerAlias("MachineTagDto", MachineTagDto.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.gbif.api.vocabulary.InstallationType;
import org.gbif.registry.domain.ws.LegacyOrganizationBriefResponse;
import org.gbif.registry.persistence.ChallengeCodeSupportMapper;
import org.gbif.registry.persistence.mapper.dto.OrganizationGeoJsonDto;
import org.gbif.registry.persistence.mapper.params.OrganizationListParams;

import java.util.List;
Expand Down Expand Up @@ -83,4 +84,10 @@ List<Organization> hostingInstallationsOf(
List<KeyTitleResult> suggest(@Nullable @Param("q") String q);

Organization getLightweight(@Param("key") UUID key);

/**
* @return The list of organizations as geojson
*/
List<OrganizationGeoJsonDto> listGeoJson(@Param("params") OrganizationListParams params);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.gbif.registry.persistence.mapper.dto;

import java.math.BigDecimal;
import java.util.UUID;

import lombok.Data;

@Data
public class OrganizationGeoJsonDto {

private UUID key;
private String title;
private Integer numPublishedDatasets;
private BigDecimal latitude;
private BigDecimal longitude;

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
<result property="language" column="language" typeHandler="org.gbif.mybatis.type.LanguageTypeHandler" />
</resultMap>

<resultMap id="ORGANIZATION_GEOJSON_DTO_MAP" type="OrganizationGeoJsonDto" autoMapping="true">
<id property="key" column="key"/>
<result property="title" column="title" />
<association property="numPublishedDatasets" column="key" select="countPublishedDatasets" />
</resultMap>

<sql id="WRITABLE_ORGANIZATION_FIELDS">
key,endorsing_node_key,password,title,abbreviation,description,language,email,
phone,homepage,logo_url,address,city,province,country,postal_code,latitude,longitude,created,created_by,
Expand Down Expand Up @@ -485,6 +491,15 @@
</if>
</select>

<select id="listGeoJson" resultType="OrganizationGeoJsonDto" resultMap="ORGANIZATION_GEOJSON_DTO_MAP">
SELECT DISTINCT ON(<if test="params.query != null" >ts_rank_cd(o.fulltext_search, query), </if>o.created, o.key)
<include refid="ORGANIZATION_FIELDS"/>
<include refid="LIST_FILTER" />
AND o.latitude IS NOT NULL
AND o.longitude IS NOT NULL
ORDER BY <if test="params.query != null" >ts_rank_cd(o.fulltext_search, query) DESC, </if>o.created DESC, o.key
</select>

<select id="getChallengeCodeKey" resultType="Integer">
SELECT challenge_code_key FROM organization WHERE key = #{key, jdbcType=OTHER}
</select>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
import java.util.List;
import java.util.UUID;

import org.geojson.FeatureCollection;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
Expand Down Expand Up @@ -122,4 +124,9 @@ boolean confirmEndorsement(
@ResponseBody
@Override
PagingResponse<Organization> list(@SpringQueryMap OrganizationRequestSearchParams searchParams);

@GetMapping(value = "geojson", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
@Override
FeatureCollection listGeoJson(@SpringQueryMap OrganizationRequestSearchParams searchParams);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
*/
package org.gbif.registry.ws.resources;

import org.apache.ibatis.annotations.Param;

import org.gbif.api.annotation.NullToNotFound;
import org.gbif.api.annotation.Trim;
import org.gbif.api.documentation.CommonParameters;
Expand All @@ -33,6 +35,7 @@
import org.gbif.registry.persistence.mapper.DatasetMapper;
import org.gbif.registry.persistence.mapper.InstallationMapper;
import org.gbif.registry.persistence.mapper.OrganizationMapper;
import org.gbif.registry.persistence.mapper.dto.OrganizationGeoJsonDto;
import org.gbif.registry.persistence.mapper.params.BaseListParams;
import org.gbif.registry.persistence.mapper.params.DatasetListParams;
import org.gbif.registry.persistence.mapper.params.InstallationListParams;
Expand All @@ -52,6 +55,9 @@
import javax.validation.constraints.NotNull;
import javax.validation.groups.Default;

import org.geojson.Feature;
import org.geojson.FeatureCollection;
import org.geojson.Point;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
Expand Down Expand Up @@ -536,6 +542,70 @@ public List<KeyTitleResult> suggest(@RequestParam(value = "q", required = false)
return organizationMapper.suggest(label);
}

@Operation(
operationId = "listOrganizationAsGeoJson",
summary = "List all organizations as GeoJson.",
description =
"Lists all current organizations in GeoJson format (deleted organizations are not listed).",
extensions =
@Extension(
name = "Order",
properties = @ExtensionProperty(name = "Order", value = "0550")))
@SimpleSearchParameters
@Parameters(
value = {
@Parameter(
name = "isEndorsed",
description = "Whether the organization is endorsed by a node.",
schema = @Schema(implementation = Boolean.class),
in = ParameterIn.QUERY),
@Parameter(
name = "networkKey",
description = "Filter for organizations publishing datasets belonging to a network.",
schema = @Schema(implementation = UUID.class),
in = ParameterIn.QUERY)
})
@ApiResponse(responseCode = "200", description = "Organization search successful")
@ApiResponse(responseCode = "400", description = "Invalid search query provided")
@Override
@GetMapping("geojson")
public FeatureCollection listGeoJson(@Param("params") OrganizationRequestSearchParams request) {
if (request == null) {
request = new OrganizationRequestSearchParams();
}

OrganizationListParams listParams =
OrganizationListParams.builder()
.query(parseQuery(request.getQ()))
.country(request.getCountry())
.isEndorsed(request.getIsEndorsed())
.deleted(false)
.networkKey(request.getNetworkKey())
.from(parseFrom(request.getModified()))
.to(parseTo(request.getModified()))
.identifier(request.getIdentifier())
.identifierType(request.getIdentifierType())
.mtNamespace(request.getMachineTagNamespace())
.mtName(request.getMachineTagName())
.mtValue(request.getMachineTagValue())
.page(null)
.build();

List<OrganizationGeoJsonDto> publishers = organizationMapper.listGeoJson(listParams);

FeatureCollection featureCollection = new FeatureCollection();
for (OrganizationGeoJsonDto p: publishers) {
Feature feature = new Feature();
feature.setProperty("key", p.getKey());
feature.setProperty("title", p.getTitle());
feature.setProperty("numPublishedDatasets", p.getNumPublishedDatasets());
feature.setGeometry(new Point(p.getLongitude().doubleValue(), p.getLatitude().doubleValue()));
featureCollection.add(feature);
}

return featureCollection;
}

/**
* This is an HTTP only method to retrieve the shared token (password) for an organization.
*
Expand Down

0 comments on commit 6680b29

Please sign in to comment.