Skip to content

Commit

Permalink
Merge branch 'dev' into feature/extended-data
Browse files Browse the repository at this point in the history
  • Loading branch information
temi committed Feb 6, 2025
2 parents 69cd8c1 + 7406874 commit 41dfd23
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 25 deletions.
23 changes: 21 additions & 2 deletions grails-app/conf/data/mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,27 @@
"type": "text",
"index": "false"
},
"services": {
"type": "keyword"
},
"projectElectFacet": {
"type": "keyword"
},
"projectStateFacet": {
"type": "keyword"
},
"extent":{
"properties": {
"geometry": {
"properties": {

"geometry": {
"properties": {
"intersectionAreaByFacets": {
"type": "object",
"enabled": false
}
}
}

}
}
Expand All @@ -236,7 +252,10 @@
"properties": {
"geometry": {
"properties": {

"intersectionAreaByFacets": {
"type": "object",
"enabled": false
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ActivityController {
}

def get(String id) {
def detail = params.view == SCORES ? [SCORES] : []
def detail = params.view == SCORES ? [SCORES] : params.view
if (!id) {

def list = activityService.getAll(params.boolean('includeDeleted'), params.view)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ class ProjectController {
render status:400, text: "projectId is a required parameter"
} else {
Map project = projectService.get(params.projectId)
asJson projectService.findStateAndElectorateForProject(project)
asJson projectService.findAndFormatStatesAndElectoratesForProject(project)
}
}

Expand Down
13 changes: 13 additions & 0 deletions grails-app/services/au/org/ala/ecodata/ElasticSearchService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,9 @@ class ElasticSearchService {
it.remove('periodTargets')
it.remove('outcomeTargets')
} // Not useful for searching and is causing issues with the current mapping.

// add algorithmically generated or manually selected states and electorates of a project
projectMap << projectService.findStateAndElectorateForProject(projectMap)
} else {
projectMap.sites = siteService.findAllNonPrivateSitesForProjectId(project.projectId, SiteService.FLAT)
// GeoServer requires a single attribute with project area. Cannot use `sites` property (above) since it has
Expand Down Expand Up @@ -1233,6 +1236,16 @@ class ElasticSearchService {
if (!projectMap.visibility && program.inheritedConfig?.visibility) {
projectMap.visibility = program.inheritedConfig.visibility
}
List services = project.findProjectServices()

if (services) {
projectMap.services = services?.collect{
it.getProgramLabels()?[project.programId]?.label ?: it.name
}
}



}
else {
log.error("Project "+project.projectId+" references invalid program with programId = "+project.programId)
Expand Down
4 changes: 3 additions & 1 deletion grails-app/services/au/org/ala/ecodata/ParatooService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2128,7 +2128,9 @@ class ParatooService {
result.name = result.commonName ? result.scientificName ? "${result.scientificName} (${result.commonName})" : result.commonName : result.scientificName
}
else {
result.name = result.scientificName ?: result.commonName
result.name = result.scientificName
// clear common name if it is same as scientific name
result.commonName = null
}

List specialCases = grailsApplication.config.getProperty("paratoo.species.specialCases", List)
Expand Down
45 changes: 33 additions & 12 deletions grails-app/services/au/org/ala/ecodata/ProjectService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ class ProjectService {
mapOfProperties.sites = siteService.findAllForProjectId(project.projectId, [SiteService.FLAT], version)
}

// add geographic info attributes such as primarystate, otherstate, primaryelect and otherelect
mapOfProperties << findAndFormatStatesAndElectoratesForProject(mapOfProperties)
mapOfProperties.documents = documentService.findAllForProjectId(project.projectId, levelOfDetail, version)
mapOfProperties.links = documentService.findAllLinksForProjectId(project.projectId, levelOfDetail, version)
Lock lock = lockService.get(project.projectId)
Expand Down Expand Up @@ -1206,10 +1208,10 @@ class ProjectService {
Map<String,Map<String,Double>> sumOfIntersectionsByLayer = [:].withDefault { [:].withDefault { 0 } }
Map orderedIntersectionsByArea = [:]
Map config = metadataService.getGeographicConfig(project.hubId)
List layers = config.checkForBoundaryIntersectionInLayers
List layers = config?.checkForBoundaryIntersectionInLayers
List projectSites = getRepresentativeSitesOfProject(project)
projectSites?.each { Map site ->
layers.each { String layer ->
layers?.each { String layer ->
Map facet = metadataService.getGeographicFacetConfig(layer, project.hubId)
site.extent?.geometry?.get(SpatialService.INTERSECTION_AREA)?.get(facet.name)?.get(SiteService.INTERSECTION_CURRENT)?.each { String layerValue, value ->
sumOfIntersectionsByLayer[layer][layerValue] += value
Expand Down Expand Up @@ -1260,13 +1262,35 @@ class ProjectService {
[]
}

Map findAndFormatStatesAndElectoratesForProject(Map project) {
Map result = findStateAndElectorateForProject (project)
if(!result) {
return [:]
}

List elect = result.remove('projectElectFacet') as List
List state = result.remove('projectStateFacet') as List

if (state) {
result["primarystate"] = state.pop()
result["otherstate"] = state?.join("; ")
}

if (elect) {
result["primaryelect"] = elect.pop()
result["otherelect"] = elect.join("; ")
}

result
}

/**
* Find primary/other state(s)/electorate(s) for a project.
* 1. If isDefault is true, use manually assigned state(s)/electorate(s) i.e project.geographicInfo.
* 2. If isDefault is false or missing, use the state(s)/electorate(s) from sites using site precedence.
* 3. If isDefault is false and there are no sites, use manual state(s)/electorate(s) in project.geographicInfo.
*/
Map findStateAndElectorateForProject(Map project) {
Map findStateAndElectorateForProject (Map project) {
Map result = [:]
if(project == null) {
return result
Expand All @@ -1277,14 +1301,13 @@ class ProjectService {
if (geographicInfo == null || (geographicInfo.isDefault == false)) {
Map intersections = orderLayerIntersectionsByAreaOfProjectSites(project)
Map config = metadataService.getGeographicConfig()
List intersectionLayers = config.checkForBoundaryIntersectionInLayers
List intersectionLayers = config?.checkForBoundaryIntersectionInLayers
intersectionLayers?.each { layer ->
Map facetName = metadataService.getGeographicFacetConfig(layer)
if (facetName.name) {
List intersectionValues = intersections[layer]
if (intersectionValues) {
result["primary${facetName.name}"] = intersectionValues.pop()
result["other${facetName.name}"] = intersectionValues.join("; ")
result["project${facetName.name.capitalize()}Facet"] = intersectionValues
}
}
else
Expand All @@ -1295,14 +1318,12 @@ class ProjectService {
//isDefault is true or false and no sites.
if (geographicInfo) {
// load from manually assigned electorates/states
if (!result.containsKey("primaryelect")) {
result["primaryelect"] = geographicInfo.primaryElectorate
result["otherelect"] = geographicInfo.otherElectorates?.join("; ")
if (!result.containsKey("projectElectFacet")) {
result["projectElectFacet"] = (geographicInfo.primaryElectorate ? [geographicInfo.primaryElectorate] : []) + geographicInfo.otherElectorates
}

if (!result.containsKey("primarystate")) {
result["primarystate"] = geographicInfo.primaryState
result["otherstate"] = geographicInfo.otherStates?.join("; ")
if (!result.containsKey("projectStateFacet")) {
result["projectStateFacet"] = (geographicInfo.primaryState ? [geographicInfo.primaryState] : []) + geographicInfo.otherStates
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ class ProjectXlsExporter extends ProjectExporter {
}

private void addPrimaryAndOtherIntersections (Map project) {
Map result = projectService.findStateAndElectorateForProject(project) ?: [:]
Map result = projectService.findAndFormatStatesAndElectoratesForProject(project) ?: [:]
project << result
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class ActivityControllerSpec extends Specification implements ControllerUnitTest

when:
params.id = '1'
params.view = []
controller.get()

then:
Expand All @@ -67,6 +68,7 @@ class ActivityControllerSpec extends Specification implements ControllerUnitTest

when:
params.id = '2'
params.view = []
controller.get()

then:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ class ElasticSearchIndexServiceSpec extends MongoSpec implements ServiceUnitTest
then:
1 * client.index({ IndexRequest index -> index.index() == ElasticIndex.HOMEPAGE_INDEX && index.id() == projectProps.projectId}, RequestOptions.DEFAULT) >>
{ index, options -> result = new JsonSlurper().parseText(index.source().utf8ToString()); Mock(IndexResponse) }
1 * projectService.findStateAndElectorateForProject(_) >> [:]
1 * projectService.toMap(project, ProjectService.FLAT) >> projectProps

and:
Expand Down Expand Up @@ -396,6 +397,7 @@ class ElasticSearchIndexServiceSpec extends MongoSpec implements ServiceUnitTest
then:
1 * client.index({ IndexRequest index -> index.index() == ElasticIndex.HOMEPAGE_INDEX && index.id() == meritProjectProps.projectId}, RequestOptions.DEFAULT) >>
{ index, options -> meritResult = new JsonSlurper().parseText(index.source().utf8ToString()); Mock(IndexResponse) }
1 * projectService.findStateAndElectorateForProject(_) >> [:]
1 * projectService.toMap(meritProject, ProjectService.FLAT) >> meritProjectProps
1 * siteService.findAllForProjectId(meritProject.projectId, SiteService.FLAT) >> [site1]

Expand Down Expand Up @@ -492,7 +494,7 @@ class ElasticSearchIndexServiceSpec extends MongoSpec implements ServiceUnitTest

then:
1 * projectService.toMap(project, ProjectService.FLAT) >> meritProjectProps

1 * projectService.findStateAndElectorateForProject(_) >> [:]
1 * client.get(_, _) >> getResponse
1 * getResponse.exists >> true
1 * client.delete(_, _)
Expand Down
12 changes: 11 additions & 1 deletion src/test/groovy/au/org/ala/ecodata/ParatooServiceSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -815,13 +815,23 @@ class ParatooServiceSpec extends MongoSpec implements ServiceUnitTest<ParatooSer
]
0 * speciesReMatchService.searchByName(_, false, true)

when: // user inputs scientific name to field and ALA cannot match the name
result = service.transformSpeciesName("Centipeda cunninghamii")
outputSpeciesId = result.remove("outputSpeciesId")

then:
outputSpeciesId != null
result == [name: "Centipeda cunninghamii", scientificName: "Centipeda cunninghamii", commonName: null, taxonRank: null, guid: "A_GUID"]
1 * speciesReMatchService.searchByName(_) >> null
1 * speciesReMatchService.searchByName(_, false, true) >> null

when: // Do not create record when value equals special cases. Therefore, removes guid.
result = service.transformSpeciesName("Other")
outputSpeciesId = result.remove("outputSpeciesId")

then:
outputSpeciesId != null
result == [name: "Other", scientificName: "Other", commonName: "Other", taxonRank: null]
result == [name: "Other", scientificName: "Other", commonName: null, taxonRank: null]
1 * speciesReMatchService.searchByName(_) >> null
1 * speciesReMatchService.searchByName(_, false, true) >> null

Expand Down
51 changes: 47 additions & 4 deletions src/test/groovy/au/org/ala/ecodata/ProjectServiceSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,49 @@ class ProjectServiceSpec extends MongoSpec implements ServiceUnitTest<ProjectSer
result["cl11163"][2] == "canberra"
}
void "orderLayerIntersectionsByAreaOfProjectSites should order shapes over points"() {
setup:
Map projectMap
Map result
Project project1
Site site1, site2, site3
Site.metaClass.getDbo = {
delegate.properties
}
metadataService.getGeographicConfig(_) >> [
contextual: [
elect : 'cl11163'
],
"checkForBoundaryIntersectionInLayers" : [ "cl11163" ]
]
metadataService.getGeographicFacetConfig("cl11163", "12345") >> [name: "elect", grouped: true]
project1 = new Project(projectId: '111', name: "Project 111", hubId:"12345", isMERIT: true)
site1 = new Site(siteId: 's1', name: "Site 1", type: "surveyArea", status: 'active', projects: ['111'], extent: [ source: "point", geometry: [intersectionAreaByFacets: ["elect": ["CURRENT": ["fenner": 0]]]]])
site2 = new Site(siteId: 's2', name: "Site 2", type: "surveyArea", status: 'active', projects: ['111'], extent: [ source: "drawn", geometry: [intersectionAreaByFacets: ["elect": ["CURRENT": ["bean": 0.7, "canberra": 0.4]]]]])
site3 = new Site(siteId: 's3', name: "Site 3", type: "surveyArea", status: 'active', projects: ['111'], extent: [ source: "point", geometry: [intersectionAreaByFacets: ["elect": ["CURRENT": ["adelaide": 0]]]]])
Project.withTransaction {
project1.save(flush: true, failOnError: true)
site1.save(flush: true, failOnError: true)
site2.save(flush: true, failOnError: true)
site3.save(flush: true, failOnError: true)
}
project1.metaClass.getDbo = { new BasicDBObject(project1.properties) }
when:
Project.withTransaction {
projectMap = service.toMap(project1, ProjectService.ALL)
}
result = service.orderLayerIntersectionsByAreaOfProjectSites(projectMap)
then:
result.size() == 1
result["cl11163"][0] == "bean"
result["cl11163"][1] == "canberra"
["fenner", "adelaide"].contains(result["cl11163"][2])
["fenner", "adelaide"].contains(result["cl11163"][3])
}
void "getRepresentativeSitesOfProject should get EMSA site or Reporting sites only" () {
setup:
Expand Down Expand Up @@ -1118,7 +1161,7 @@ class ProjectServiceSpec extends MongoSpec implements ServiceUnitTest<ProjectSer
metadataService.getGeographicFacetConfig("layer2", _) >> [name: "elect", grouped: false]
when:
Map result = service.findStateAndElectorateForProject(project)
Map result = service.findAndFormatStatesAndElectoratesForProject(project)
then:
result.primarystate == "state1"
Expand All @@ -1142,7 +1185,7 @@ class ProjectServiceSpec extends MongoSpec implements ServiceUnitTest<ProjectSer
when:
Map result = service.findStateAndElectorateForProject(project)
Map result = service.findAndFormatStatesAndElectoratesForProject(project)
then:
result.primarystate == "ACT"
Expand All @@ -1157,7 +1200,7 @@ class ProjectServiceSpec extends MongoSpec implements ServiceUnitTest<ProjectSer
Map project = [geographicInfo: [isDefault: true, primaryState: "ACT", otherStates: ['NSW', 'VIC'], primaryElectorate: "Bean", otherElectorates: ['Canberra', 'Fenner']]]
when:
Map result = service.findStateAndElectorateForProject(project)
Map result = service.findAndFormatStatesAndElectoratesForProject(project)
then:
result.primarystate == "ACT"
Expand All @@ -1169,7 +1212,7 @@ class ProjectServiceSpec extends MongoSpec implements ServiceUnitTest<ProjectSer
def "findStateAndElectorateForProject should return empty map if project is null"() {
when:
Map project = null
Map result = service.findStateAndElectorateForProject(project)
Map result = service.findAndFormatStatesAndElectoratesForProject(project)
then:
result.isEmpty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ class ProjectXlsExporterSpec extends Specification implements GrailsUnitTest {
setup:
String sheet = "Electorate Coord"
Map project = project()
projectService.findStateAndElectorateForProject(_) >> ["primarystate": "ACT", "otherstate": null, "primaryelect": "bean", "otherelect": "fenner; canberra"]
projectService.findAndFormatStatesAndElectoratesForProject(_) >> ["primarystate": "ACT", "otherstate": null, "primaryelect": "bean", "otherelect": "fenner; canberra"]

when:
projectXlsExporter.export(project)
Expand Down

0 comments on commit 41dfd23

Please sign in to comment.