diff --git a/src/main/java/no/nibio/vips/logic/entity/ForecastResult.java b/src/main/java/no/nibio/vips/logic/entity/ForecastResult.java index 51c9842986cacae5f01c4e6283d8bd8b00020bac..4d4d1f2a269835f7a293dc96ccdb1478861ba883 100755 --- a/src/main/java/no/nibio/vips/logic/entity/ForecastResult.java +++ b/src/main/java/no/nibio/vips/logic/entity/ForecastResult.java @@ -96,6 +96,7 @@ public class ForecastResult implements Serializable, Comparable{ this.allValues = new ObjectMapper().writeValueAsString(result.getAllValues()); this.validTimeStart = result.getValidTimeStart(); this.warningStatus = result.getWarningStatus(); + this.validGeometry = result.getValidGeometry(); } catch (IOException ex) { Logger.getLogger(ForecastResult.class.getName()).log(Level.SEVERE, null, ex); } diff --git a/src/main/java/no/nibio/vips/logic/scheduling/model/grid/preprocessor/ZymoseptoriaSimpleRiskGridModelPreprocessor.java b/src/main/java/no/nibio/vips/logic/scheduling/model/grid/preprocessor/ZymoseptoriaSimpleRiskGridModelPreprocessor.java new file mode 100644 index 0000000000000000000000000000000000000000..5dbb30805c441b0d7b53de2a881dbe79ecdee4ce --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/scheduling/model/grid/preprocessor/ZymoseptoriaSimpleRiskGridModelPreprocessor.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2018 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ + +package no.nibio.vips.logic.scheduling.model.grid.preprocessor; + +import com.vividsolutions.jts.geom.Coordinate; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import no.nibio.vips.entity.ModelConfiguration; +import no.nibio.vips.entity.PointWeatherObservationList; +import no.nibio.vips.entity.WeatherObservation; +import no.nibio.vips.logic.entity.ForecastConfiguration; +import no.nibio.vips.logic.entity.PointOfInterestWeatherStation; +import no.nibio.vips.logic.scheduling.model.ModelRunPreprocessor; +import no.nibio.vips.logic.scheduling.model.PreprocessorException; +import no.nibio.vips.logic.util.SessionControllerGetter; +import no.nibio.vips.util.WeatherElements; +import no.nibio.vips.util.WeatherObservationListException; +import no.nibio.vips.util.WeatherUtil; +import no.nibio.vips.util.weather.WeatherDataSourceException; +import no.nibio.vips.util.weather.WeatherDataSourceUtil; + +/** + * @copyright 2018 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class ZymoseptoriaSimpleRiskGridModelPreprocessor extends ModelRunPreprocessor{ + + @Override + public ModelConfiguration getModelConfiguration(ForecastConfiguration configuration) throws PreprocessorException { + ModelConfiguration modelConfig = new ModelConfiguration(); + // Which weather stations?? + // Ilseng and Apelsvoll to start with ;-) + List<PointOfInterestWeatherStation> stations = Stream.of(new Integer[]{50,91}).map( + stationId -> (PointOfInterestWeatherStation) SessionControllerGetter.getPointOfInterestBean().getPointOfInterest(stationId) + ).collect(Collectors.toList()); + + List<PointWeatherObservationList> allObs = new ArrayList<>(); + + for(PointOfInterestWeatherStation station:stations) + { + Coordinate coordinate = new Coordinate(station.getPointOfInterest().getLongitude(), station.getPointOfInterest().getLatitude()); + List<WeatherObservation> stationObs = getStationObs(station, configuration); + PointWeatherObservationList pointObs = new PointWeatherObservationList(coordinate, stationObs); + allObs.add(pointObs); + } + + modelConfig.setConfigParameter("multiPointWeatherObservations", allObs); + modelConfig.setModelId(this.getModelId()); + modelConfig.setConfigParameter("timeZone", stations.get(0).getTimeZone()); + return modelConfig; + } + + @Override + public String getModelId() { + return "GRIDZYMOSE"; + } + + private List<WeatherObservation> getStationObs(PointOfInterestWeatherStation station, ForecastConfiguration configuration) throws PreprocessorException + { + List<WeatherObservation> stationObs;// = new ArrayList<>(); + WeatherDataSourceUtil wdsUtil = new WeatherDataSourceUtil(); + WeatherUtil wUtil = new WeatherUtil(); + try { + + stationObs = wdsUtil.getWeatherObservations( + station, + WeatherObservation.LOG_INTERVAL_ID_1H, + new String[]{ + WeatherElements.LEAF_WETNESS, + WeatherElements.RELATIVE_HUMIDITY_MEAN, + WeatherElements.PRECIPITATION, + WeatherElements.TEMPERATURE_MEAN + }, + configuration.getDateStartInTimeZone(), + configuration.getDateEndInTimeZone(), + true + ); + stationObs = wUtil.checkForAndFixHourlyTimeSeriesHoles(stationObs); + return stationObs; + } catch (WeatherDataSourceException | WeatherObservationListException ex ) { + throw new PreprocessorException(ex.getMessage()); + } + } +} diff --git a/src/main/java/no/nibio/vips/logic/scheduling/tasks/RunGridModelsTask.java b/src/main/java/no/nibio/vips/logic/scheduling/tasks/RunGridModelsTask.java new file mode 100644 index 0000000000000000000000000000000000000000..4502a914f8b1a6de106d7821c0eb2fd0344b04dc --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/scheduling/tasks/RunGridModelsTask.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ + +package no.nibio.vips.logic.scheduling.tasks; + +import it.sauronsoftware.cron4j.TaskExecutionContext; +import java.util.Calendar; +import no.nibio.vips.logic.entity.ForecastConfiguration; +import no.nibio.vips.logic.entity.VipsLogicUser; +import no.nibio.vips.logic.scheduling.SchedulingUtil; +import no.nibio.vips.logic.scheduling.VipsLogicTask; +import no.nibio.vips.logic.scheduling.VipsLogicTaskFactory; +import no.nibio.vips.logic.scheduling.model.PreprocessorException; +import no.nibio.vips.logic.scheduling.model.grid.preprocessor.ZymoseptoriaSimpleRiskGridModelPreprocessor; +import no.nibio.vips.logic.util.RunModelException; +import no.nibio.vips.logic.util.SessionControllerGetter; +import no.nibio.vips.logic.util.SystemTime; +import no.nibio.web.forms.FormField; + +/** + * @copyright 2018 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class RunGridModelsTask extends VipsLogicTask{ + + @Override + public String getConfigFormDefinition(String language) { + return "{\"fields\":[]}"; + } + + @Override + public void execute(TaskExecutionContext tec) throws RuntimeException { + tec.setCompleteness(0.0); + //ZymoseptoriaSimpleRiskGridModelPreprocessor pp = new ZymoseptoriaSimpleRiskGridModelPreprocessor(); + // TODO: Must find a forecast configuration id! -1000 ! + + ForecastConfiguration fConfig = SessionControllerGetter.getForecastBean().getForecastConfiguration(-1000l); + + try + { + SessionControllerGetter.getForecastBean().runForecast(fConfig); + tec.setCompleteness(1.0); + } + catch(PreprocessorException | RunModelException ex) + { + tec.setCompleteness(0.0); + tec.setStatusMessage(SchedulingUtil.createSchedulingMessageHTML( + "Error with forecast #" + fConfig.getForecastConfigurationId(), + ex.getMessage(), + SchedulingUtil.MESSAGE_STATUS_DANGER + ) + ); + + ex.printStackTrace(); + throw new RuntimeException(); + } + } + + @Override + public boolean supportsStatusTracking() + { + return true; + } + + @Override + public boolean supportsCompletenessTracking() + { + return true; + } +} diff --git a/src/main/java/no/nibio/vips/logic/util/GISEntityUtil.java b/src/main/java/no/nibio/vips/logic/util/GISEntityUtil.java index ab1b52c1b369cd23330d772d29591b5a833e7c21..2b0d3b27b195d26fe55f17462f7928e81da68f24 100755 --- a/src/main/java/no/nibio/vips/logic/util/GISEntityUtil.java +++ b/src/main/java/no/nibio/vips/logic/util/GISEntityUtil.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import no.nibio.vips.gis.GISUtil; import no.nibio.vips.logic.entity.Gis; import no.nibio.vips.logic.entity.Observation; import org.wololo.geojson.Feature; @@ -79,7 +80,7 @@ public class GISEntityUtil { { Gis gis = new Gis(); gis.setGisGeom(reader.read(feature.getGeometry())); - gis.getGisGeom().setSRID(4326); + gis.getGisGeom().setSRID(GISUtil.DEFAULT_SRID); retVal.add(gis); } }catch(NullPointerException ex) {}; diff --git a/src/main/java/no/nibio/vips/util/weather/WeatherDataSourceUtil.java b/src/main/java/no/nibio/vips/util/weather/WeatherDataSourceUtil.java index 2c97e4430e221c5a9412d7711dbe3171e6717d14..6369833ca3dd78e329891df9d392987f49850cc2 100755 --- a/src/main/java/no/nibio/vips/util/weather/WeatherDataSourceUtil.java +++ b/src/main/java/no/nibio/vips/util/weather/WeatherDataSourceUtil.java @@ -59,11 +59,12 @@ public class WeatherDataSourceUtil { * @param elementMeasurementTypes Which parameters should be fetched * @param startTime When to start * @param endTime When to stop + * @param ignoreErrors if true, accepts errors and missing data from source * @return * @throws PreprocessorException */ - public List<WeatherObservation> getWeatherObservations(PointOfInterestWeatherStation station, Integer logIntervalId, String[] elementMeasurementTypes, Date startTime, Date endTime) throws WeatherDataSourceException { - List<WeatherObservation> observations = this.getWeatherObservations(station.getDataFetchUri(), logIntervalId, elementMeasurementTypes, startTime, endTime, TimeZone.getTimeZone(station.getTimeZone())); + public List<WeatherObservation> getWeatherObservations(PointOfInterestWeatherStation station, Integer logIntervalId, String[] elementMeasurementTypes, Date startTime, Date endTime, Boolean ignoreErrors) throws WeatherDataSourceException { + List<WeatherObservation> observations = this.getWeatherObservations(station.getDataFetchUri(), logIntervalId, elementMeasurementTypes, startTime, endTime, TimeZone.getTimeZone(station.getTimeZone()), ignoreErrors); Collections.sort(observations); Date latestTimeOfMeasuredObservations = observations.isEmpty() ? null : observations.get(observations.size() - 1).getTimeMeasured(); if (station.getWeatherForecastProviderId() != null) { @@ -113,6 +114,30 @@ public class WeatherDataSourceUtil { return observations; } + /** + * Fetches measured data from the stations weather data source, and optionally + * a weather forecast provider (if so specified in the weather station configuration). + * Regarding weather forecast parameters: All requested parameters need be present in the + * forecast in order for any parameters to be fetched. So if you request e.g. TJM5 and TM, + * you won't get forecast values for any of them, because TJM5 is not present. Solve this + * by calling this method twice: Once for the parameters with forecasts, and one for the + * remaining. + * + * Requires the source to provide a complete data set (still, no guarantee) + * + * @param station The WeatherStation to fetch data from + * @param logIntervalId hourly/daily etc. + * @param elementMeasurementTypes Which parameters should be fetched + * @param startTime When to start + * @param endTime When to stop + * @return + * @throws PreprocessorException + */ + public List<WeatherObservation> getWeatherObservations(PointOfInterestWeatherStation station, Integer logIntervalId, String[] elementMeasurementTypes, Date startTime, Date endTime) throws WeatherDataSourceException + { + return this.getWeatherObservations(station, logIntervalId, elementMeasurementTypes, startTime, endTime, Boolean.FALSE); + } + public List<WeatherObservation> getWeatherObservations(String JSONtext) throws IOException { return new ObjectMapper().readValue(JSONtext, new TypeReference<List<WeatherObservation>>() { }); @@ -128,15 +153,26 @@ public class WeatherDataSourceUtil { * @param timeZone * @return */ - public List<WeatherObservation> getWeatherObservations(String fetchURI, Integer logIntervalId, String[] elementMeasurementTypes, Date startTime, Date endTime, TimeZone timeZone) throws WeatherDataSourceException { + public List<WeatherObservation> getWeatherObservations(String fetchURI, Integer logIntervalId, String[] elementMeasurementTypes, Date startTime, Date endTime, TimeZone timeZone, Boolean ignoreErrors) throws WeatherDataSourceException { SimpleDateFormat dateOutput = new SimpleDateFormat("yyyy-MM-dd"); dateOutput.setTimeZone(timeZone); SimpleDateFormat hourOutput = new SimpleDateFormat("H"); hourOutput.setTimeZone(timeZone); - StringBuilder URL = new StringBuilder(fetchURI).append(fetchURI.contains("?") ? "&" : "?").append("logIntervalId=").append(logIntervalId).append("&timeZone=").append(timeZone.getID()).append("&startDate=").append(dateOutput.format(startTime)).append("&startTime=").append(hourOutput.format(startTime)).append("&endDate=").append(dateOutput.format(endTime)).append("&endTime=").append(hourOutput.format(endTime)); + StringBuilder URL = new StringBuilder(fetchURI) + .append(fetchURI.contains("?") ? "&" : "?") + .append("logIntervalId=").append(logIntervalId) + .append("&timeZone=").append(timeZone.getID()) + .append("&startDate=").append(dateOutput.format(startTime)) + .append("&startTime=").append(hourOutput.format(startTime)) + .append("&endDate=").append(dateOutput.format(endTime)) + .append("&endTime=").append(hourOutput.format(endTime)); for (String type : elementMeasurementTypes) { URL.append("&elementMeasurementTypes[]=").append(type); } + if(ignoreErrors) + { + URL.append("&ignoreErrors=true"); + } URLConnection URLConn = null; InputStream URLStream = null; InputStream error = null; diff --git a/src/main/resources/db/migration/V2__POI_Changes.sql b/src/main/resources/db/migration/V2__POI_Changes.sql new file mode 100644 index 0000000000000000000000000000000000000000..a9bb42bcf528ecd294ff8e3be37c1d478ad23b08 --- /dev/null +++ b/src/main/resources/db/migration/V2__POI_Changes.sql @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +/** + * Author: Tor-Einar Skog <tor-einar.skog@nibio.no> + * Created: Feb 28, 2018 + */ + +-- Create POI type region as entity +CREATE TABLE public.point_of_interest_region ( + point_of_interest_id INTEGER REFERENCES public.point_of_interest(point_of_interest_id) PRIMARY KEY REFERENCES public.point_of_interest(point_of_interest_id) +); +-- Create Region +INSERT INTO public.point_of_interest_type (point_of_interest_type_id, default_name) VALUES(4, 'Region'); +-- Create the "Norden" region +WITH region AS( + INSERT INTO public.point_of_interest(name, point_of_interest_type_id, time_zone, user_id, gis_geom, is_forecast_location) + VALUES('Norden',4,'Europe/Oslo', (SELECT user_id FROM public.vips_logic_user WHERE first_name='Tor-Einar' and last_name='Skog'), + ST_GeomFromText('POLYGON Z ((11.551171875 67.9220301158979 0,14.7591796875 69.4854724192637 0,16.73671875 69.8064521798385 0,18.14296875 70.5952718386758 0,21.394921875 71.0142675856785 0,24.5150390625 71.5222863520185 0,28.426171875 71.438536696887 0,30.09609375 71.0713720920153 0,32.117578125 70.5952718386758 0,32.20546875 70.2120731914377 0,31.2826171875 69.8064521798384 0,31.062890625 69.4392213779 0,30.2279296875 69.3619145496807 0,29.656640625 69.1908599706792 0,29.04140625 68.7811487475743 0,28.865625 68.3637499431732 0,29.656640625 68.0866206437207 0,30.3158203125 67.6788323570344 0,29.480859375 66.9328949304538 0,30.44765625 65.8776814440396 0,30.4037109375 65.606865608295 0,30.0521484375 65.3698520724687 0,30.271875 65.1306805628583 0,29.9203125 64.9266077088153 0,30.6234375 64.8146360164186 0,30.359765625 64.4948403042286 0,30.887109375 64.2286381683626 0,30.44765625 63.7079270727349 0,31.6341796875 63.2170897962889 0,31.9857421875 62.6976281054899 0,27.371484375 60.0026032393766 0,26.844140625 59.9586321882202 0,28.3822265625 59.6713938591578 0,28.5140625 59.1120223258653 0,27.898828125 58.7719510110943 0,27.898828125 58.2439712430728 0,28.1625 57.7314817865778 0,28.6458984375 56.2961712709242 0,26.844140625 54.9817652590221 0,25.965234375 53.960342078609 0,23.5482421875 53.5446062737309 0,23.1966796875 54.0894167790577 0,22.36171875 54.3463659023544 0,22.4056640625 54.8048547300243 0,17.5716796875 56.1495794720281 0,14.8470703125 54.4742415202341 0,11.7708984375 54.3719729342547 0,7.46425781249998 55.0069747908166 0,7.37636718749998 57.4488421356283 0,5.61855468749998 57.8953424124117 0,4.21230468749998 59.1571122721993 0,3.77285156249998 61.776544291261 0,5.09121093749999 62.858445992293 0,9.39785156249999 64.8146360164187 0,11.3314453125 66.8984342861737 0,10.9359375 67.5617094491323 0,11.551171875 67.9220301158979 0))',4326), false) +RETURNING * +) +INSERT INTO public.point_of_interest_region(point_of_interest_id) SELECT region.point_of_interest_id FROM region; diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties index be0f3e8604122d7860381871b75ed3aff39eda3a..26eae52a23c2dba8934029232f8cbcc11063bdbd 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties @@ -450,3 +450,6 @@ lastEditedBy=Last edited by clusterStored=The cluster information was stored internal=Internal vipsLogicRole_8=Apple Fruit Moth Rowanberry Cluster Counter +pointOfInterestType_4=Region +task_RunGridModelsTask_name=Run grid models +task_RunGridModelsTask_description=Run models that cover several locations diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties index ab21ac6ef474c5061d75e49148df793a065ae74d..3af974595514b02ea7cd37927c89cd475d0c7b9b 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties @@ -450,3 +450,6 @@ lastEditedBy=Last edited by clusterStored=The cluster information was stored internal=Internal vipsLogicRole_8=Apple Fruit Moth Rowanberry Cluster Counter +pointOfInterestType_4=Region +task_RunGridModelsTask_name=Run grid models +task_RunGridModelsTask_description=Test diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties index ef4a7939fa5e2dfa30441fd9d879694ea12eebf2..eaa5d435a8bd68ce9d57cf4006fd7afef59fe9ec 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties @@ -449,3 +449,6 @@ lastEditedBy=Last edited by clusterStored=The cluster information was stored internal=Internal vipsLogicRole_8=Apple Fruit Moth Rowanberry Cluster Counter +pointOfInterestType_4=Region +task_RunGridModelsTask_name=Run grid models +task_RunGridModelsTask_description=Test diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties index e65302b4b87abf08a62f50c8b679f0e023d42b86..2a899f2b96badcbdff19f96b2ead9933873ecb4f 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties @@ -450,3 +450,6 @@ lastEditedBy=Sist redigert av clusterStored=Klasetallene ble registrert internal=Internt vipsLogicRole_8=Rogneb\u00e6rm\u00f8llklaseteller +pointOfInterestType_4=Region +task_RunGridModelsTask_name=Kj\u00f8r GRID-baserte modeller +task_RunGridModelsTask_description=Kj\u00f8r modeller som spenner over flere lokaliteter diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties index 287e0bef04e00386715eb2a69742b71736c228fd..f722af4d1a0f29ef27d2142d7ddd68117206cc13 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties @@ -450,3 +450,6 @@ lastEditedBy=Last edited by clusterStored=The cluster information was stored internal=Internal vipsLogicRole_8=Apple Fruit Moth Rowanberry Cluster Counter +pointOfInterestType_4=Region +task_RunGridModelsTask_name=Run grid models +task_RunGridModelsTask_description=Test diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties index 670f92f20929f5e1490b3e5cbc92bed5af5c2239..979001d6760254038ceed8c5326ee8f551dc8519 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties @@ -447,3 +447,6 @@ lastEditedBy=Last edited by clusterStored=The cluster information was stored internal=Internal vipsLogicRole_8=Apple Fruit Moth Rowanberry Cluster Counter +pointOfInterestType_4=Region +task_RunGridModelsTask_name=Run grid models +task_RunGridModelsTask_description=Test