diff --git a/.gitignore b/.gitignore
index 879e777462..224ec1a346 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,10 @@
-.DS_Store
-**/target/**
+**/target/**
+/modules/ExcelCsvImporter/build/
+/modules/ExcelCsvImporter/nbproject/private/
+/ExcelCsvImporter/build/
+/ExcelCsvImporter/nbproject/private/
+/target/
+/MapOfCountries/build/
+/MapOfCountries/nbproject/private/
+/ExcelCsvImporter_/build/
+/ExcelCsvImporter_/nbproject/private/
\ No newline at end of file
diff --git a/modules/MapOfCountries/Apache v2.txt b/modules/MapOfCountries/Apache v2.txt
new file mode 100644
index 0000000000..100491c57a
--- /dev/null
+++ b/modules/MapOfCountries/Apache v2.txt
@@ -0,0 +1,55 @@
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/modules/MapOfCountries/pom.xml b/modules/MapOfCountries/pom.xml
new file mode 100644
index 0000000000..a4552472ef
--- /dev/null
+++ b/modules/MapOfCountries/pom.xml
@@ -0,0 +1,63 @@
+
+
+ 4.0.0
+
+ gephi-plugin-parent
+ org.gephi
+ 0.9.1
+
+
+ net
+ clementlevallois
+ 1.0.0
+ nbm
+
+ MapOfCountries
+
+
+
+
+ org.netbeans.api
+ org-openide-util-lookup
+
+
+ org.gephi
+ graph-api
+
+
+ org.gephi
+ layout-plugin
+
+
+ org.netbeans.api
+ org-openide-util
+
+
+ org.gephi
+ layout-api
+
+
+ org.gephi
+ ui-propertyeditor
+
+
+
+
+
+
+ org.codehaus.mojo
+ nbm-maven-plugin
+
+ Apache v2
+ Apache v2.txt
+ Clement Levallois
+ https://github.com/seinecle/gephi-plugins/tree/mapOfCountriesBranch
+ http://www.clementlevallois.net
+
+
+
+
+
+
+
+
diff --git a/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/AbstractPropertyEditorForCountries.java b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/AbstractPropertyEditorForCountries.java
new file mode 100644
index 0000000000..dd45070e90
--- /dev/null
+++ b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/AbstractPropertyEditorForCountries.java
@@ -0,0 +1,73 @@
+/*
+Copyright 2008 WebAtlas
+Authors : Mathieu Bastian, Mathieu Jacomy, Julian Bilcke
+Website : http://www.gephi.org
+
+This file is part of Gephi.
+
+Gephi is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Gephi 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
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gephi. If not, see .
+ */
+package net.clementlevallois.mapofcountries;
+
+import java.beans.PropertyEditorSupport;
+
+/**
+ *
+ * @author Alexis Jacomy
+ */
+abstract class AbstractPropertyEditorForCountries extends PropertyEditorSupport {
+
+ protected AbstractPropertyEditorForCountries() {
+ }
+
+ private String selectedRow;
+
+ @Override
+ public String[] getTags() {
+ return GeoLayout.COUNTRIES;
+ }
+
+ @Override
+ public Object getValue() {
+ return selectedRow;
+ }
+
+ @Override
+ public void setValue(Object value) {
+ for(int i=0;i.
+ */
+package net.clementlevallois.mapofcountries;
+
+import java.beans.PropertyEditorSupport;
+
+/**
+ *
+ * @author Alexis Jacomy
+ */
+abstract class AbstractPropertyEditorForDistricts extends PropertyEditorSupport {
+
+ protected AbstractPropertyEditorForDistricts() {
+ }
+
+ private String selectedRow;
+
+ @Override
+ public String[] getTags() {
+ return GeoLayout.DISTRICTS;
+ }
+
+ @Override
+ public Object getValue() {
+ return selectedRow;
+ }
+
+ @Override
+ public void setValue(Object value) {
+ for(int i=0;i.
+ */
+package net.clementlevallois.mapofcountries;
+
+import java.beans.PropertyEditorSupport;
+
+/**
+ *
+ * @author Alexis Jacomy
+ */
+abstract class AbstractPropertyEditorForProjections extends PropertyEditorSupport {
+
+ protected AbstractPropertyEditorForProjections() {
+ }
+
+ private String selectedRow;
+
+ @Override
+ public String[] getTags() {
+ return GeoLayout.PROJECTIONS;
+ }
+
+ @Override
+ public Object getValue() {
+ return selectedRow;
+ }
+
+ @Override
+ public void setValue(Object value) {
+ for(int i=0;i.
+ */
+package net.clementlevallois.mapofcountries;
+
+import java.beans.PropertyEditorSupport;
+
+/**
+ *
+ * @author Alexis Jacomy
+ */
+abstract class AbstractPropertyEditorForRegions extends PropertyEditorSupport {
+
+ protected AbstractPropertyEditorForRegions() {
+ }
+
+ private String selectedRow;
+
+ @Override
+ public String[] getTags() {
+ return GeoLayout.REGIONS;
+ }
+
+ @Override
+ public Object getValue() {
+ return selectedRow;
+ }
+
+ @Override
+ public void setValue(Object value) {
+ for(int i=0;i.
+ */
+package net.clementlevallois.mapofcountries;
+
+import java.beans.PropertyEditorSupport;
+
+/**
+ *
+ * @author Alexis Jacomy
+ */
+abstract class AbstractPropertyEditorForSubRegions extends PropertyEditorSupport {
+
+ protected AbstractPropertyEditorForSubRegions() {
+ }
+
+ private String selectedRow;
+
+ @Override
+ public String[] getTags() {
+ return GeoLayout.SUBREGIONS;
+ }
+
+ @Override
+ public Object getValue() {
+ return selectedRow;
+ }
+
+ @Override
+ public void setValue(Object value) {
+ for(int i=0;i.
+ */
+package net.clementlevallois.mapofcountries;
+
+import java.beans.PropertyEditorSupport;
+
+/**
+ *
+ * @author Alexis Jacomy
+ */
+abstract class AbstractPropertyEditorForWeight extends PropertyEditorSupport {
+
+ protected AbstractPropertyEditorForWeight() {
+ }
+
+ private String selectedRow;
+
+ @Override
+ public String[] getTags() {
+ return GeoLayout.COUNTRIES;
+ }
+
+ @Override
+ public Object getValue() {
+ return selectedRow;
+ }
+
+ @Override
+ public void setValue(Object value) {
+ for(int i=0;i.
+ */
+package net.clementlevallois.mapofcountries;
+
+/**
+ *
+ * @author Alexis Jacomy
+ */
+public class CustomComboBoxEditorForCountries extends AbstractPropertyEditorForCountries {
+ public CustomComboBoxEditorForCountries() {
+ super();
+ }
+}
diff --git a/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForDistricts.java b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForDistricts.java
new file mode 100644
index 0000000000..e641078638
--- /dev/null
+++ b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForDistricts.java
@@ -0,0 +1,31 @@
+/*
+Copyright 2008 WebAtlas
+Authors : Mathieu Bastian, Mathieu Jacomy, Julian Bilcke
+Website : http://www.gephi.org
+
+This file is part of Gephi.
+
+Gephi is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Gephi 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
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gephi. If not, see .
+ */
+package net.clementlevallois.mapofcountries;
+
+/**
+ *
+ * @author Alexis Jacomy
+ */
+public class CustomComboBoxEditorForDistricts extends AbstractPropertyEditorForDistricts {
+ public CustomComboBoxEditorForDistricts() {
+ super();
+ }
+}
diff --git a/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForProjections.java b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForProjections.java
new file mode 100644
index 0000000000..8d6bb7d357
--- /dev/null
+++ b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForProjections.java
@@ -0,0 +1,31 @@
+/*
+Copyright 2008 WebAtlas
+Authors : Mathieu Bastian, Mathieu Jacomy, Julian Bilcke
+Website : http://www.gephi.org
+
+This file is part of Gephi.
+
+Gephi is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Gephi 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
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gephi. If not, see .
+ */
+package net.clementlevallois.mapofcountries;
+
+/**
+ *
+ * @author Alexis Jacomy
+ */
+public class CustomComboBoxEditorForProjections extends AbstractPropertyEditorForProjections {
+ public CustomComboBoxEditorForProjections() {
+ super();
+ }
+}
diff --git a/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForRegions.java b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForRegions.java
new file mode 100644
index 0000000000..3760783257
--- /dev/null
+++ b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForRegions.java
@@ -0,0 +1,31 @@
+/*
+Copyright 2008 WebAtlas
+Authors : Mathieu Bastian, Mathieu Jacomy, Julian Bilcke
+Website : http://www.gephi.org
+
+This file is part of Gephi.
+
+Gephi is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Gephi 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
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gephi. If not, see .
+ */
+package net.clementlevallois.mapofcountries;
+
+/**
+ *
+ * @author Alexis Jacomy
+ */
+public class CustomComboBoxEditorForRegions extends AbstractPropertyEditorForRegions {
+ public CustomComboBoxEditorForRegions() {
+ super();
+ }
+}
diff --git a/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForSubRegions.java b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForSubRegions.java
new file mode 100644
index 0000000000..cac44abe63
--- /dev/null
+++ b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/CustomComboBoxEditorForSubRegions.java
@@ -0,0 +1,31 @@
+/*
+Copyright 2008 WebAtlas
+Authors : Mathieu Bastian, Mathieu Jacomy, Julian Bilcke
+Website : http://www.gephi.org
+
+This file is part of Gephi.
+
+Gephi is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Gephi 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
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gephi. If not, see .
+ */
+package net.clementlevallois.mapofcountries;
+
+/**
+ *
+ * @author Alexis Jacomy
+ */
+public class CustomComboBoxEditorForSubRegions extends AbstractPropertyEditorForSubRegions {
+ public CustomComboBoxEditorForSubRegions() {
+ super();
+ }
+}
diff --git a/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/GeoLayout.java b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/GeoLayout.java
new file mode 100644
index 0000000000..956b243e71
--- /dev/null
+++ b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/GeoLayout.java
@@ -0,0 +1,636 @@
+/*
+ Copyright 2008-2013 Clement Levallois
+ Authors : Clement Levallois
+ Website : http://www.clementlevallois.net
+
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright 2013 Clement Levallois. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 3 only ("GPL") or the Common
+ Development and Distribution License("CDDL") (collectively, the
+ "License"). You may not use this file except in compliance with the
+ License. You can obtain a copy of the License at
+ http://gephi.org/about/legal/license-notice/
+ or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
+ specific language governing permissions and limitations under the
+ License. When distributing the software, include this License Header
+ Notice in each file and include the License files at
+ /cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
+ License Header, with the fields enclosed by brackets [] replaced by
+ your own identifying information:
+ "Portions Copyrighted [year] [name of copyright owner]"
+
+ If you wish your version of this file to be governed by only the CDDL
+ or only the GPL Version 3, indicate your decision by adding
+ "[Contributor] elects to include this software in this distribution
+ under the [CDDL or GPL Version 3] license." If you do not indicate a
+ single choice of license, a recipient has the option to distribute
+ your version of this file under either the CDDL, the GPL Version 3 or
+ to extend the choice of license to its licensees as provided above.
+ However, if you add GPL Version 3 code and therefore, elected the GPL
+ Version 3 license, then the option applies only if the new code is
+ made subject to such option by the copyright holder.
+
+ Contributor(s): Clement Levallois
+ */
+package net.clementlevallois.mapofcountries;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.MissingResourceException;
+import java.util.ArrayList;
+import org.gephi.graph.api.Graph;
+import org.gephi.graph.api.GraphModel;
+import org.gephi.graph.api.Node;
+import org.gephi.graph.spi.LayoutData;
+import org.gephi.layout.spi.Layout;
+import org.gephi.layout.spi.LayoutBuilder;
+import org.gephi.layout.spi.LayoutProperty;
+import org.openide.util.NbBundle;
+import org.gephi.graph.api.Column;
+import org.gephi.graph.api.Edge;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author Clement Levallois
+ */
+public final class GeoLayout implements Layout {
+
+ private final GeoLayoutBuilder builder;
+ private GraphModel graphModel;
+ private boolean cancel;
+ //Params
+ private double scale = 1000;
+ private boolean centered = true;
+ private Column latitude;
+ private Column longitude;
+ private String projection = "Mercator";
+ private String region = "No region";
+ private String subregion = "No subregion";
+ private String district = "No district";
+ private String country = "World";
+ public static String[] PROJECTIONS = {"Mercator", "Transverse Mercator", "Miller cylindrical", "Gall–Peters", "Sinusoidal", "Lambert cylindrical", "Equirectangular", "Winkel tripel"};
+ public static String[] COUNTRIES = {"World", "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory", "British Virgin Islands", "Brunei Darussalam", "Bulgaria", "Burkina Faso", "Burma", "Burundi", "Cambodia", "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo", "Cook Islands", "Costa Rica", "Cote d'Ivoire", "Croatia", "Cuba", "Cyprus", "Czech Republic", "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Falkland Islands (Malvinas)", "Faroe Islands", "Fiji", "Finland", "France", "French Guiana", "French Polynesia", "French Southern and Antarctic Lands", "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guernsey", "Guinea", "Guinea-Bissau", "Guyana", "Haiti", "Heard Island and McDonald Islands", "Holy See (Vatican City)", "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran (Islamic Republic of)", "Iraq", "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Korea, Democratic People's Republic of", "Korea, Republic of", "Kuwait", "Kyrgyzstan", "Lao People's Democratic Republic", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libyan Arab Jamahiriya", "Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia, Federated States of", "Monaco", "Mongolia", "Montenegro", "Montserrat", "Morocco", "Mozambique", "Namibia", "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", "Palestine", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar", "Republic of Moldova", "Reunion", "Romania", "Russia", "Rwanda", "Saint Barthelemy", "Saint Helena", "Saint Kitts and Nevis", "Saint Lucia", "Saint Martin", "Saint Pierre and Miquelon", "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", "South Georgia South Sandwich Islands", "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard", "Swaziland", "Sweden", "Switzerland", "Syrian Arab Republic", "Taiwan", "Tajikistan", "Thailand", "The former Yugoslav Republic of Macedonia", "Timor-Leste", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United Republic of Tanzania", "United States", "United States Minor Outlying Islands", "United States Virgin Islands", "Uruguay", "Uzbekistan", "Vanuatu", "Venezuela", "Viet Nam", "Wallis and Futuna Islands", "Western Sahara", "Yemen", "Zambia", "Zimbabwe", "Åland Islands"};
+ public static String[] REGIONS = {"No region", "Africa", "Americas", "Asia", "Europe", "Europe (without Russia)", "Oceania"};
+ public static String[] SUBREGIONS = {"No subregion", "Eastern Africa", "Niddle Africa", "Northern Africa", "Southern Africa", "Western Africa", "Caribbean", "Central America", "South America", "Northern America", "Central Asia", "Eastern Asia", "Southern Asia", "South-Eastern Asia", "Western Asia", "Eastern Europe", "Northern Europe", "Southern Europe", "Western Europe", "Australia and New Zealand", "Melanesia", "Micronesia", "Polynesia"};
+ public static String[] DISTRICTS = {"No district", "Australia_Victoria", "Australia_New South Wales", "Australia_Queensland", "Australia_Tasmania", "Australia_Northern Territory", "Australia_Western Australia", "Australia_South Australia", "Australia_Other Territories", "Australia_Australian Capital Territory"};
+ public Float weight = 1f;
+
+ public GeoLayout(GeoLayoutBuilder builder) {
+ this.builder = builder;
+ resetPropertiesValues();
+ }
+
+ public void resetPropertiesValues() {
+ }
+
+ public void initAlgo() {
+ cancel = false;
+ }
+
+ public void goAlgo() {
+ try {
+ double lon = 0;
+ double lat = 0;
+ float nodeX = 0;
+ float nodeY = 0;
+ float averageX = 0;
+ float averageY = 0;
+ Graph graph = graphModel.getGraph();
+
+ if (!graphModel.getNodeTable().hasColumn("background_map")){
+ graphModel.getNodeTable().addColumn("background_map", Boolean.class);
+ }
+
+ if (!graphModel.getNodeTable().hasColumn("lat")){
+ graphModel.getNodeTable().addColumn("lat", Double.class);
+ }
+
+ if (!graphModel.getNodeTable().hasColumn("lng")){
+ graphModel.getNodeTable().addColumn("lng", Double.class);
+ }
+
+ ShapeFileReader shapeFileReader = new ShapeFileReader();
+ graph = shapeFileReader.read(graph, country, subregion, region, district);
+ Iterator it = graphModel.getNodeTable().iterator();
+ Column c;
+ while (it.hasNext()) {
+ c = it.next();
+ if (c.getId().equalsIgnoreCase("lat") || c.getTitle().equalsIgnoreCase("lat")) {
+ latitude = c;
+ } else if (c.getId().equalsIgnoreCase("lng") || c.getTitle().equalsIgnoreCase("lng")) {
+ longitude = c;
+ }
+ }
+ List nodesList = new ArrayList();
+ for (Node n : graph.getNodes().toArray()) {
+ if (Boolean.TRUE.equals(n.getAttribute("background_map"))) {
+ nodesList.add(n);
+ }
+ }
+ Node[] nodes = nodesList.toArray(new Node[nodesList.size()]);
+ ArrayList validNodes = new ArrayList();
+ ArrayList invalidNodes = new ArrayList();
+ for (Node n : nodes) {
+ if (n.getAttribute(latitude) != null && n.getAttribute(longitude) != null) {
+ if (Math.abs(((Number) n.getAttribute(longitude)).doubleValue()) == 180d) {
+ graph.removeNode(n);
+ continue;
+ }
+
+ if (Math.abs(((Number) n.getAttribute(latitude)).doubleValue()) == 90d) {
+ graph.removeNode(n);
+ continue;
+ }
+
+ validNodes.add(n);
+ } else {
+ invalidNodes.add(n);
+ }
+ }
+ for (Edge e : graph.getEdges().toArray()) {
+ Node nodeSource = e.getSource();
+ Node nodeTarget = e.getTarget();
+ if (nodeSource.getAttribute("background_map") != null || nodeTarget.getAttribute("background_map") != null) {
+ e.setWeight(this.weight);
+ }
+ }
+
+ if (projection.equals("Mercator")) {
+ double lambda0 = 0;
+
+ //determine lambda0:
+ for (Node n : validNodes) {
+ lon = ((Number) n.getAttribute(longitude)).doubleValue();
+ lambda0 += lon;
+ }
+
+ lambda0 = lambda0 / validNodes.size();
+ lambda0 = Math.toRadians(lambda0);
+
+ //apply the formula:
+ for (Node n : validNodes) {
+ if (n.getLayoutData() == null || !(n.getLayoutData() instanceof GeoLayoutData)) {
+ n.setLayoutData(new GeoLayoutData());
+ }
+
+
+ lat = ((Number) n.getAttribute(latitude)).doubleValue();
+ lon = ((Number) n.getAttribute(longitude)).doubleValue();
+
+ lat = Math.toRadians(lat);
+ lon = Math.toRadians(lon);
+
+ nodeX = (float) ((lon - lambda0) * scale);
+ nodeY = (float) ((Math.log(Math.tan(Math.PI / 4 + lat / 2))) * scale);
+
+ averageX += nodeX;
+ averageY += nodeY;
+
+ n.setX(nodeX);
+ n.setY(nodeY);
+ }
+
+ averageX = averageX / validNodes.size();
+ averageY = averageY / validNodes.size();
+ } // Transverse Mercator
+ else if (projection.equals("Transverse Mercator")) {
+ //apply the formula:
+ for (Node n : validNodes) {
+ if (n.getLayoutData() == null || !(n.getLayoutData() instanceof GeoLayoutData)) {
+ n.setLayoutData(new GeoLayoutData());
+ }
+
+
+ lat = ((Number) n.getAttribute(latitude)).doubleValue();
+ lon = ((Number) n.getAttribute(longitude)).doubleValue();
+
+ lat = Math.toRadians(lat);
+ lon = Math.toRadians(lon);
+
+ nodeX = (float) (lon * scale);
+ nodeY = (float) (scale / 2 * Math.log((1 + Math.sin(lat)) / (1 - Math.sin(lat))));
+
+ averageX += nodeX;
+ averageY += nodeY;
+
+ n.setX(nodeX);
+ n.setY(nodeY);
+ }
+
+ averageX = averageX / validNodes.size();
+ averageY = averageY / validNodes.size();
+ } // Miller cylindrical
+ else if (projection.equals("Miller cylindrical")) {
+ //apply the formula:
+ for (Node n : validNodes) {
+ if (n.getLayoutData() == null || !(n.getLayoutData() instanceof GeoLayoutData)) {
+ n.setLayoutData(new GeoLayoutData());
+ }
+
+
+
+ lat = ((Number) n.getAttribute(latitude)).doubleValue();
+ lon = ((Number) n.getAttribute(longitude)).doubleValue();
+
+ lat = Math.toRadians(lat);
+ lon = Math.toRadians(lon);
+
+ nodeX = (float) (lon * scale);
+ nodeY = (float) (Math.log(Math.tan(Math.PI / 4 + 2 * lat / 5)) * scale * 5 / 4);
+
+ averageX += nodeX;
+ averageY += nodeY;
+
+ n.setX(nodeX);
+ n.setY(nodeY);
+ }
+
+ averageX = averageX / validNodes.size();
+ averageY = averageY / validNodes.size();
+ } // Gall–Peters
+ else if (projection.equals("Gall–Peters")) {
+ //apply the formula:
+ for (Node n : validNodes) {
+ if (n.getLayoutData() == null || !(n.getLayoutData() instanceof GeoLayoutData)) {
+ n.setLayoutData(new GeoLayoutData());
+ }
+
+
+
+ lat = ((Number) n.getAttribute(latitude)).doubleValue();
+ lon = ((Number) n.getAttribute(longitude)).doubleValue();
+
+ lat = Math.toRadians(lat);
+ lon = Math.toRadians(lon);
+
+ nodeX = (float) (lon * scale);
+ nodeY = (float) (2 * scale * Math.sin(lat));
+
+ averageX += nodeX;
+ averageY += nodeY;
+
+ n.setX(nodeX);
+ n.setY(nodeY);
+ }
+
+ averageX = averageX / validNodes.size();
+ averageY = averageY / validNodes.size();
+ } // Sinusoidal
+ else if (projection.equals("Sinusoidal")) {
+ double lambda0 = 0;
+ //determine lambda0:
+ for (Node n : validNodes) {
+
+ lon = ((Number) n.getAttribute(longitude)).doubleValue();
+ lambda0 += lon;
+ }
+
+ lambda0 = lambda0 / validNodes.size();
+ lambda0 = Math.toRadians(lambda0);
+
+ //apply the formula:
+ for (Node n : validNodes) {
+ if (n.getLayoutData() == null || !(n.getLayoutData() instanceof GeoLayoutData)) {
+ n.setLayoutData(new GeoLayoutData());
+ }
+
+
+
+ lat = ((Number) n.getAttribute(latitude)).doubleValue();
+ lon = ((Number) n.getAttribute(longitude)).doubleValue();
+
+ lat = Math.toRadians(lat);
+ lon = Math.toRadians(lon);
+
+ nodeX = (float) ((lon - lambda0) * Math.cos(lat) * scale);
+ nodeY = (float) (scale * lat);
+
+ averageX += nodeX;
+ averageY += nodeY;
+
+ n.setX(nodeX);
+ n.setY(nodeY);
+ }
+
+ averageX = averageX / validNodes.size();
+ averageY = averageY / validNodes.size();
+ } // Lambert cylindrical equal-area
+ else if (projection.equals("Lambert cylindrical")) {
+ double lambda0 = 0;
+ double phi0 = 0;
+
+ //determine lambda0:
+ for (Node n : validNodes) {
+
+ lat = ((Number) n.getAttribute(latitude)).doubleValue();
+ lon = ((Number) n.getAttribute(longitude)).doubleValue();
+ lambda0 += lon;
+ phi0 += lat;
+ }
+
+ lambda0 = lambda0 / validNodes.size();
+ phi0 = phi0 / validNodes.size();
+
+ lambda0 = Math.toRadians(lambda0);
+ phi0 = Math.toRadians(phi0);
+
+ //apply the formula:
+ for (Node n : validNodes) {
+ if (n.getLayoutData() == null || !(n.getLayoutData() instanceof GeoLayoutData)) {
+ n.setLayoutData(new GeoLayoutData());
+ }
+
+
+ lat = ((Number) n.getAttribute(latitude)).doubleValue();
+ lon = ((Number) n.getAttribute(longitude)).doubleValue();
+
+ lat = Math.toRadians(lat);
+ lon = Math.toRadians(lon);
+
+ nodeX = (float) ((lon - lambda0) * Math.cos(phi0) * scale);
+ nodeY = (float) (scale * Math.sin(lat) / Math.cos(phi0));
+
+ averageX += nodeX;
+ averageY += nodeY;
+
+ n.setX(nodeX);
+ n.setY(nodeY);
+ }
+
+ averageX = averageX / validNodes.size();
+ averageY = averageY / validNodes.size();
+ } // Equirectangular
+ else if (projection.equals("Equirectangular")) {
+
+ //apply the formula:
+ for (Node n : validNodes) {
+ if (n.getLayoutData() == null || !(n.getLayoutData() instanceof GeoLayoutData)) {
+ n.setLayoutData(new GeoLayoutData());
+ }
+
+
+ lat = ((Number) n.getAttribute(latitude)).doubleValue();
+ lon = ((Number) n.getAttribute(longitude)).doubleValue();
+
+ lat = Math.toRadians(lat);
+ lon = Math.toRadians(lon);
+
+ nodeX = (float) (scale * lon);
+ nodeY = (float) (scale * lat);
+
+ averageX += nodeX;
+ averageY += nodeY;
+
+ n.setX(nodeX);
+ n.setY(nodeY);
+ }
+
+ averageX = averageX / validNodes.size();
+ averageY = averageY / validNodes.size();
+ } // Winkel tripel
+ else if (projection.equals("Winkel tripel")) {
+ double alpha = 0;
+
+ //apply the formula:
+ for (Node n : validNodes) {
+ if (n.getLayoutData() == null || !(n.getLayoutData() instanceof GeoLayoutData)) {
+ n.setLayoutData(new GeoLayoutData());
+ }
+
+
+ lat = ((Number) n.getAttribute(latitude)).doubleValue();
+ lon = ((Number) n.getAttribute(longitude)).doubleValue();
+
+ lat = Math.toRadians(lat);
+ lon = Math.toRadians(lon);
+
+ alpha = Math.acos(Math.cos(lon / 2) * 2 / Math.PI);
+
+ nodeX = (float) (scale * ((lon * 2 / Math.PI) + (2 * Math.cos(lat) * Math.sin(lon / 2) * alpha / Math.sin(alpha))));
+ nodeY = (float) (scale * (lat + Math.sin(lat) * alpha / Math.sin(alpha)));
+
+ averageX += nodeX;
+ averageY += nodeY;
+
+ n.setX(nodeX);
+ n.setY(nodeY);
+ }
+
+ averageX = averageX / validNodes.size();
+ averageY = averageY / validNodes.size();
+ }
+
+ if (validNodes.size() > 0 && invalidNodes.size() > 0) {
+ Node tempNode = validNodes.get(0);
+ double xMin = tempNode.x();
+ double xMax = tempNode.x();
+ double yMin = tempNode.y();
+ double xTemp = 0;
+ double yTemp = 0;
+
+ for (Node n : validNodes) {
+ xTemp = n.x();
+ yTemp = n.y();
+
+ if (xTemp < xMin) {
+ xMin = xTemp;
+ }
+ if (xTemp > xMax) {
+ xMax = xTemp;
+ }
+ if (yTemp < yMin) {
+ yMin = yTemp;
+ }
+ }
+
+ if (invalidNodes.size() > 1) {
+ double i = 0;
+ double step = (xMax - xMin) / (invalidNodes.size() - 1);
+ for (Node n : invalidNodes) {
+ n.setX((float) (xMin + i * step));
+ n.setY((float) (yMin - step));
+ i++;
+ }
+ } else {
+ tempNode = invalidNodes.get(0);
+ tempNode.setX(10000);
+ tempNode.setY(10000);
+ }
+ }
+
+ if (centered == true) {
+ for (Node n : nodes) {
+ nodeX = n.x() - averageX;
+ nodeY = n.y() - averageY;
+
+ n.setX(nodeX);
+ n.setY(nodeY);
+ }
+ }
+ cancel = true;
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+
+ public void endAlgo() {
+ }
+
+ @Override
+ public boolean canAlgo() {
+ return !cancel;
+ }
+
+ public LayoutProperty[] getProperties() {
+ List properties = new ArrayList();
+ final String GEOLAYOUT = "Geo Layout";
+
+ try {
+ properties.add(LayoutProperty.createProperty(
+ this, String.class,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.countries.name"),
+ GEOLAYOUT,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.countries.desc"),
+ "getCountry", "setCountry", CustomComboBoxEditorForCountries.class));
+
+ properties.add(LayoutProperty.createProperty(
+ this, String.class,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.subregions.name"),
+ GEOLAYOUT,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.subregions.desc"),
+ "getSubregion", "setSubregion", CustomComboBoxEditorForSubRegions.class));
+
+ properties.add(LayoutProperty.createProperty(
+ this, String.class,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.regions.name"),
+ GEOLAYOUT,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.regions.desc"),
+ "getRegion", "setRegion", CustomComboBoxEditorForRegions.class));
+
+ properties.add(LayoutProperty.createProperty(
+ this, String.class,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.districts.name"),
+ GEOLAYOUT,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.districts.desc"),
+ "getDistrict", "setDistrict", CustomComboBoxEditorForDistricts.class));
+
+ properties.add(LayoutProperty.createProperty(
+ this, Double.class,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.scale.name"),
+ GEOLAYOUT,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.scale.desc"),
+ "getScale", "setScale"));
+ properties.add(LayoutProperty.createProperty(
+ this, Float.class,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.weight.name"),
+ GEOLAYOUT,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.weight.desc"),
+ "getWeight", "setWeight"));
+ properties.add(LayoutProperty.createProperty(
+ this, String.class,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.projection.name"),
+ GEOLAYOUT,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.projection.desc"),
+ "getProjection", "setProjection", CustomComboBoxEditorForProjections.class));
+ properties.add(LayoutProperty.createProperty(
+ this, Boolean.class,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.centered.name"),
+ GEOLAYOUT,
+ NbBundle.getMessage(GeoLayout.class, "GeoLayout.centered.desc"),
+ "isCentered", "setCentered"));
+ } catch (MissingResourceException e) {
+ Exceptions.printStackTrace(e);
+ } catch (NoSuchMethodException e) {
+ Exceptions.printStackTrace(e);
+ }
+
+ return properties.toArray(new LayoutProperty[0]);
+ }
+
+ public Boolean isCentered() {
+ return centered;
+ }
+
+ public void setCentered(Boolean centered) {
+ this.centered = centered;
+ }
+
+ public String getProjection() {
+ return projection;
+ }
+
+ public void setProjection(String projection) {
+ this.projection = projection;
+ }
+
+ public void setGraphModel(GraphModel graphModel) {
+ this.graphModel = graphModel;
+ }
+
+ public LayoutBuilder getBuilder() {
+ return builder;
+ }
+
+ public Double getScale() {
+ return scale;
+ }
+
+ public void setScale(Double scale) {
+ this.scale = scale;
+ }
+
+ public Float getWeight() {
+ return weight;
+ }
+
+ public void setWeight(Float weight) {
+ this.weight = weight;
+ }
+
+
+ private static class GeoLayoutData implements LayoutData {
+
+ //Data
+ public double x = 0f;
+ public double y = 0f;
+ }
+
+ public String getRegion() {
+ return region;
+ }
+
+ public void setRegion(String region) {
+ this.region = region;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ public String getSubregion() {
+ return subregion;
+ }
+
+ public void setSubregion(String subregion) {
+ this.subregion = subregion;
+ }
+
+ public String getDistrict() {
+ return district;
+ }
+
+ public void setDistrict(String district) {
+ this.district = district;
+ }
+
+}
diff --git a/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/GeoLayoutBuilder.java b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/GeoLayoutBuilder.java
new file mode 100644
index 0000000000..6eda4fa923
--- /dev/null
+++ b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/GeoLayoutBuilder.java
@@ -0,0 +1,91 @@
+/*
+ Copyright 2008-2013 Clement Levallois
+ Authors : Clement Levallois
+ Website : http://www.clementlevallois.net
+
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright 2013 Clement Levallois. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 3 only ("GPL") or the Common
+ Development and Distribution License("CDDL") (collectively, the
+ "License"). You may not use this file except in compliance with the
+ License. You can obtain a copy of the License at
+ http://gephi.org/about/legal/license-notice/
+ or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
+ specific language governing permissions and limitations under the
+ License. When distributing the software, include this License Header
+ Notice in each file and include the License files at
+ /cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
+ License Header, with the fields enclosed by brackets [] replaced by
+ your own identifying information:
+ "Portions Copyrighted [year] [name of copyright owner]"
+
+ If you wish your version of this file to be governed by only the CDDL
+ or only the GPL Version 3, indicate your decision by adding
+ "[Contributor] elects to include this software in this distribution
+ under the [CDDL or GPL Version 3] license." If you do not indicate a
+ single choice of license, a recipient has the option to distribute
+ your version of this file under either the CDDL, the GPL Version 3 or
+ to extend the choice of license to its licensees as provided above.
+ However, if you add GPL Version 3 code and therefore, elected the GPL
+ Version 3 license, then the option applies only if the new code is
+ made subject to such option by the copyright holder.
+
+ Contributor(s): Clement Levallois
+ */
+package net.clementlevallois.mapofcountries;
+
+import javax.swing.Icon;
+import javax.swing.JPanel;
+import org.gephi.layout.spi.Layout;
+import org.gephi.layout.spi.LayoutBuilder;
+import org.gephi.layout.spi.LayoutUI;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ *
+ * @author Clement Levallois
+ */
+@ServiceProvider(service = LayoutBuilder.class)
+public class GeoLayoutBuilder implements LayoutBuilder {
+
+ private final GeoLayoutUI ui = new GeoLayoutUI();
+
+ public String getName() {
+ return "Map of Countries";
+ }
+
+ public LayoutUI getUI() {
+ return ui;
+ }
+
+ public Layout buildLayout() {
+ return new GeoLayout(this);
+ }
+
+ private static class GeoLayoutUI implements LayoutUI {
+
+ public String getDescription() {
+ return "Insert maps of countries and world regions in Gephi";
+ }
+
+ public Icon getIcon() {
+ return null;
+ }
+
+ public JPanel getSimplePanel(Layout layout) {
+ return null;
+ }
+
+ public int getQualityRank() {
+ return -1;
+ }
+
+ public int getSpeedRank() {
+ return -1;
+ }
+ }
+}
diff --git a/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/ShapeFileReader.java b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/ShapeFileReader.java
new file mode 100644
index 0000000000..0da0d850e7
--- /dev/null
+++ b/modules/MapOfCountries/src/main/java/net/clementlevallois/mapofcountries/ShapeFileReader.java
@@ -0,0 +1,237 @@
+/*
+ Copyright 2008-2013 Clement Levallois
+ Authors : Clement Levallois
+ Website : http://www.clementlevallois.net
+
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright 2013 Clement Levallois. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 3 only ("GPL") or the Common
+ Development and Distribution License("CDDL") (collectively, the
+ "License"). You may not use this file except in compliance with the
+ License. You can obtain a copy of the License at
+ http://gephi.org/about/legal/license-notice/
+ or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
+ specific language governing permissions and limitations under the
+ License. When distributing the software, include this License Header
+ Notice in each file and include the License files at
+ /cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
+ License Header, with the fields enclosed by brackets [] replaced by
+ your own identifying information:
+ "Portions Copyrighted [year] [name of copyright owner]"
+
+ If you wish your version of this file to be governed by only the CDDL
+ or only the GPL Version 3, indicate your decision by adding
+ "[Contributor] elects to include this software in this distribution
+ under the [CDDL or GPL Version 3] license." If you do not indicate a
+ single choice of license, a recipient has the option to distribute
+ your version of this file under either the CDDL, the GPL Version 3 or
+ to extend the choice of license to its licensees as provided above.
+ However, if you add GPL Version 3 code and therefore, elected the GPL
+ Version 3 license, then the option applies only if the new code is
+ made subject to such option by the copyright holder.
+
+ Contributor(s): Clement Levallois
+ */
+package net.clementlevallois.mapofcountries;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+import org.gephi.graph.api.Edge;
+import org.gephi.graph.api.Graph;
+import org.gephi.graph.api.GraphController;
+import org.gephi.graph.api.GraphModel;
+import org.gephi.graph.api.Node;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Clement Levallois
+ */
+public class ShapeFileReader {
+
+ private final Map regionCodes = new HashMap();
+ private final Map subregionCodes = new HashMap();
+ private final Map districtCodes = new HashMap();
+
+ public Graph read(Graph gr, String country, String subregion, String region, String district) throws IOException {
+
+ regionsCodeLoader();
+ subregionsCodeLoader();
+ districtsCodeLoader();
+
+ //removing previous map
+ for (Node n : gr.getNodes().toArray()) {
+ if (Boolean.TRUE.equals(n.getAttribute("background_map"))) {
+ gr.removeNode(n);
+ }
+ }
+
+ InputStream shapes = ShapeFileReader.class.getResourceAsStream("/resources/coordinates.txt");
+ InputStream shapesDistricts = ShapeFileReader.class.getResourceAsStream("/resources/Australian states.csv");
+ GraphController gc = Lookup.getDefault().lookup(GraphController.class);
+ GraphModel gm = gc.getGraphModel();
+
+ gr = gm.getGraph();
+
+ Node node;
+ Edge edge;
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(shapes));
+ BufferedReader brDistricts = new BufferedReader(new InputStreamReader(shapesDistricts));
+
+ String line;
+ while ((line = br.readLine()) != null) {
+ String[] fields = line.split("\t");
+ String countryName = fields[0].split(":")[1];
+ String regionName = fields[1].split(":")[1];
+ String subregionName = fields[2].split(":")[1];
+
+ if (countryName == null || countryName.isEmpty()) {
+ continue;
+ }
+ if (!subregion.equals("No subregion")) {
+ if (!subregionName.equals(subregionCodes.get(subregion))) {
+ continue;
+ }
+ } else if (!region.equals("No region")) {
+ if (!regionName.equals(regionCodes.get(region))) {
+ continue;
+ }
+ if (region.equals("Europe (without Russia)")) {
+ if (countryName.equals("Russia")) {
+ continue;
+ }
+ }
+ } else if (!country.equals("World") & !countryName.equals(country)) {
+ continue;
+ }
+ if (!district.equals("No district")) {
+ continue;
+ }
+
+ for (int i = 3; i < fields.length; i++) {
+ if (fields[i].startsWith("node")) {
+ String nodeId = "bckm_"+fields[i].split(":")[0].replace("node", "").trim();
+ String lat = fields[i].split(":")[1].split(" ")[1].trim();
+ String lng = fields[i].split(":")[1].split(" ")[0].trim();
+ node = gm.factory().newNode(nodeId);
+ node.setSize(0f);
+ node.setAttribute("background_map", true);
+ node.setAttribute("lat", Double.valueOf(lat));
+ node.setAttribute("lng", Double.valueOf(lng));
+ node.setFixed(true);
+ gr.addNode(node);
+ }
+ if (fields[i].startsWith("edge")) {
+ String sourceNode = "bckm_" + fields[i].trim().split(":")[1].trim().split(" ")[0].trim();
+ String targetNode = "bckm_" + fields[i].trim().split(":")[1].trim().split(" ")[1].trim();
+ edge = gm.factory().newEdge(gr.getNode(sourceNode), gr.getNode(targetNode), 0, 1d, false);
+ gr.addEdge(edge);
+ }
+ }
+ }
+ br.close();
+
+ if (district.equals("No district")) {
+ return gr;
+ }
+
+ while ((line = brDistricts.readLine()) != null) {
+ String[] fields = line.split("\t");
+ String districtName = fields[3].split(":")[1];
+
+ if (!districtName.equals(districtCodes.get(district))) {
+ continue;
+ }
+
+ for (int i = 4; i < fields.length; i++) {
+ if (fields[i].startsWith("node")) {
+ String nodeId = "bckm_"+fields[i].split(":")[0].replace("node", "").trim();
+ String lat = fields[i].split(":")[1].split(" ")[1].trim();
+ String lng = fields[i].split(":")[1].split(" ")[0].trim();
+ node = gm.factory().newNode(nodeId);
+ node.setSize(0f);
+ node.setAttribute("background_map", true);
+ node.setAttribute("lat", Double.valueOf(lat));
+ node.setAttribute("lng", Double.valueOf(lng));
+ node.setFixed(true);
+ gr.addNode(node);
+ }
+ if (fields[i].startsWith("edge")) {
+ String sourceNode = "bckm_"+fields[i].trim().split(":")[1].trim().split(" ")[0].trim();
+ String targetNode = "bckm_"+fields[i].trim().split(":")[1].trim().split(" ")[1].trim();
+ edge = gm.factory().newEdge(gr.getNode(sourceNode), gr.getNode(targetNode), 0, 1d, false);
+ gr.addEdge(edge);
+ }
+ }
+ }
+ brDistricts.close();
+ return gr;
+
+ }
+
+ private void regionsCodeLoader() {
+
+ regionCodes.put("Africa", "2");
+ regionCodes.put("Americas", "19");
+ regionCodes.put("Asia", "142");
+ regionCodes.put("Europe", "150");
+ regionCodes.put("Europe (without Russia)", "150");
+ regionCodes.put("Oceania", "9");
+
+ }
+
+ private void districtsCodeLoader() {
+
+ districtCodes.put("Australia_New South Wales", "1");
+ districtCodes.put("Australia_Victoria", "2");
+ districtCodes.put("Australia_Queensland", "3");
+ districtCodes.put("Australia_South Australia", "4");
+ districtCodes.put("Australia_Western Australia", "5");
+ districtCodes.put("Australia_Tasmania", "6");
+ districtCodes.put("Australia_Northern Territory", "7");
+ districtCodes.put("Australia_Australian Capital Territory", "8");
+ districtCodes.put("Australia_Other Territories", "9");
+
+ }
+
+ private void subregionsCodeLoader() {
+
+ subregionCodes.put("Eastern Africa", "14");
+ subregionCodes.put("Middle Africa", "17");
+ subregionCodes.put("Northern Africa", "15");
+ subregionCodes.put("Southern Africa", "18");
+ subregionCodes.put("Western Africa", "11");
+
+ subregionCodes.put("Caribbean", "29");
+ subregionCodes.put("Central America", "13");
+ subregionCodes.put("South America", "5");
+
+ subregionCodes.put("Northern America", "21");
+
+ subregionCodes.put("Central Asia", "143");
+ subregionCodes.put("Eastern Asia", "30");
+ subregionCodes.put("Southern Asia", "34");
+ subregionCodes.put("South-Eastern Asia", "35");
+ subregionCodes.put("Western Asia", "145");
+
+ subregionCodes.put("Eastern Europe", "151");
+ subregionCodes.put("Northern Europe", "154");
+ subregionCodes.put("Southern Europe", "39");
+ subregionCodes.put("Western Europe", "155");
+
+ subregionCodes.put("Australia and New Zealand", "53");
+ subregionCodes.put("Melanesia", "54");
+ subregionCodes.put("Micronesia", "57");
+ subregionCodes.put("Polynesia", "61");
+
+ }
+}
diff --git a/modules/MapOfCountries/src/main/nbm/manifest.mf b/modules/MapOfCountries/src/main/nbm/manifest.mf
new file mode 100644
index 0000000000..01d31836b7
--- /dev/null
+++ b/modules/MapOfCountries/src/main/nbm/manifest.mf
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+OpenIDE-Module-Localizing-Bundle: net/clementlevallois/mapofcountries/Bundle.properties
diff --git a/modules/MapOfCountries/src/main/resources/net/clementlevallois/mapofcountries/Bundle.properties b/modules/MapOfCountries/src/main/resources/net/clementlevallois/mapofcountries/Bundle.properties
new file mode 100644
index 0000000000..83f556d55a
--- /dev/null
+++ b/modules/MapOfCountries/src/main/resources/net/clementlevallois/mapofcountries/Bundle.properties
@@ -0,0 +1,44 @@
+OpenIDE-Module-Display-Category=Layout
+OpenIDE-Module-Long-Description=\
+ Map of Countries
\nThis plugin allows you to displays maps of countries, world regions, and regions within countries that you choose from a list. \
+ This can be useful if you want to plot geolocalized networks on it.\
+
\n
\n\nRelease history
\nSept. 24, 2013: 1.0, first release
\nOct 19, 2014: 1.1, removed labels from background nodes because they were just an inconvenience.\n\
+ Jan 1, 2015: 1.2, fixed a null pointer exception.\
+
\nMay 13, 2015: 1.3, added a new feature: districts and regions from countries. \
+ Australian states / territories are the first addition.\
+
\nAug 05, 2015: 1.4, added a new feature: "Weight" allows to control the thickness of the lines of the borders
\n
\n\n